Element 节点 (元素节点)
是一组对象
对应网页的 HTML 元素
每一个 HTML 元素,在 DOM 树上都会转化成一个 Element 节点对象(以下简称元素节点)
所有元素节点的 nodeType 属性都是 1
浏览器使用不同的构造函数,生成不同的元素节点,有各自构造函数的属性和方法
- <a> 元素的节点对象由 HTMLAnchorElement 构造函数生成
- <button> 元素的节点对象由 HTMLButtonElement 构造函数生成
-
元素特性的相关属性
- Element.id
- 指定元素的
id
属性,该属性可读写,
- 指定元素的
- Element.id
- Element.tagName
- 指定元素的大写标签名,大小写敏感
- Element.tagName
- Element.dir
- 用于读写当前元素的文字方向 ltr 或者 rtl
- Element.dir
- Element.accessKey
- 用于读写分配给当前元素的快捷键
-
// HTML 代码如下
// <button accesskey="h" id="btn">点击</button>
var btn = document.getElementById('btn');
btn.accessKey // "h"上面代码中,btn元素的快捷键是h,按下 Alt + h 就能将焦点转移到它上面
- Element.accessKey
- Element.draggable
- 返回一个布尔值,表示当前元素是否可拖动。该属性可读写
- Element.draggable
- Element.lang
- 返回当前元素的语言设置。该属性可读写
- Element.lang
- Element.tabIndex
- 返回一个整数,表示当前元素在 Tab 键遍历时的顺序。该属性可读写。
- 如果是负值(通常是-1),则 Tab 键不会遍历到该元素。
- 如果是正整数,则按照顺序,从小到大遍历。
- 如果两个元素的 tabIndex 属性的正整数值相同,则按照出现的顺序遍历。
- 遍历完所有 tabIndex 为正整数的元素以后,再遍历所有 tabIndex 等于0、或者属性值是非法值、或者没有 tabIndex 属性的元素,顺序为它们在网页中出现的顺序
- 返回一个整数,表示当前元素在 Tab 键遍历时的顺序。该属性可读写。
- Element.tabIndex
- Element.title
- 用来读写当前元素的 HTML 属性 title。
- 指定鼠标悬浮时弹出的文字提示框
- Element.title
-
元素状态的相关属性
- Element.hidden
- 返回一个布尔值,表示当前元素的 hidden 属性,用来控制当前元素是否可见。该属性可读写
- 这个属性并不能用来判断当前元素的实际可见性。因为该属性与 CSS 设置是互相独立的
- Element.hidden
- Element.contentEditable
- 控制元素的内容是否可以编辑
- true 元素内容可编辑
- false 元素内容不可编辑
- inherit 元素是否可编辑,继承了父元素的设置
- 控制元素的内容是否可以编辑
- Element.contentEditable
- Element.isContentEditable
- 返回一个布尔值,同样表示元素的内容是否可以编辑。该属性只读。
- Element.isContentEditable
- Element.attributes
- 返回一个类似数组的对象,成员是当前元素节点的所有属性节点
- Element.attributes
- Element.className
- 读写当前元素节点的class属性。
- 它的值是一个字符串,每个 class 之间用空格分割。
- Element.className
- Element.classList
- 返回一个类似数组的对象,当前元素节点的每个 class 就是这个对象的一个成员
- classList 对象有下列方法
- add() 增加一个 class
- remove() 移除一个 class
- contains() 检查当前元素是否包含某个 class
- toggle() 将某个 class 移入或移出当前元素
- 如果为 true,则添加该属性;如果为 false,则去除该属性
el.classList.toggle('abc', boolValue); // 等同于
if (boolValue) {
el.classList.add('abc');
} else {
el.classList.remove('abc');
}
- item() 返回指定索引位置的 class
- toString() 将 class 的列表转为字符串
- 比较一下,className 和classList 在 添加 和 删除 某个 class 时的写法
var foo = document.getElementById('foo'); // 添加class
foo.className += 'bold';
foo.classList.add('bold'); // 删除class
foo.classList.remove('bold');
foo.className = foo.className.replace(/^bold$/, '');
- Element.classList
- Element.dataset
- 返回一个对象,可以从这个对象读写 data- 属性
- 网页元素可以自定义 data- 属性,用来添加数据
// <article
// id="foo"
// data-columns="3"
// data-index-number="12314"
// data-parent="cars">
// ...
// </article> var article = document.getElementById('foo');
foo.dataset.columns // "3"
foo.dataset.indexNumber // "12314"
foo.dataset.parent // "cars"
- data-属性的属性名,只能包含英文字母、数字、连词线(-)、点(.)、冒号(:)和下划线(_)。
- 它们转成 JavaScript 对应的dataset属性名,规则如下
- 开头的 data- 会省略
- 如果连词线后面跟了一个英文字母,那么连词线会取消,该字母变成大写
- 其他字符不变
// data-abc-def 对应 dataset.abcDef
// data-abc-1 对应 dataset["abc-1"]
- Element.innerHTML
- 设置某个节点的内容
- 它能改写所有元素节点的内容,包括 <HTML> 和 <body> 元素
- 如果文本之中含有 <script> 标签,虽然可以生成script节点,但是插入的代码不会执行
- 风险:
-
var name = "<img src=x onerror=alert(1)>";
el.innerHTML = name;上面代码中,alert方法是会执行的。
因此为了安全考虑,如果插入的是文本,最好用 textContent 属性代替 innerHTML
-
- Element.dataset
- Element.outerHTML
- 返回一个字符串,表示当前元素节点的所有 HTML 代码,包括该元素本身和所有子元素
- 是可读写的,对它进行赋值,等于替换掉当前元素
- 变量 d 代表子节点,它的 outerHTML 属性重新赋值以后,内层的div元素就不存在了,被 p 元素替换了。
- 但是,变量 d 依然指向原来的 div 元素,这表示被替换的 DIV 元素还存在于内存中
- 如果一个节点没有父节点,设置 outerHTML 属性会报错。
- Element.outerHTML
- Element.clientHeight
- 返回一个整数值,表示元素节点的 CSS 高度(单位像素)
- 除了元素本身的高度,它还包括 padding 部分,但是不包括 border、margin,如果元素有水平滚动条,还要减去水平滚动条的高度
- 只对块级元素生效,对于行内元素返回 0
- 如果块级元素没有设置 CSS 高度,则返回实际高度
- Element.clientHeight
- Element.clientWidth
- 返回一个整数值,表示元素节点的 CSS 宽度(单位像素)
- 除了元素本身的宽度,它还包括 padding 部分,但是不包括 border、margin,如果元素有水平滚动条,还要减去水平滚动条的宽度
- 只对块级元素生效,对于行内元素返回 0
- 如果块级元素没有设置 CSS 宽度,则返回实际宽度
- document.documentElement 的 clientHeight 属性,返回当前视口的高度(即浏览器窗口的高度)
- 浏览器窗口的高度 = window.innerHeight 属性减去水平滚动条的高度(如果有的话)
- document.body 的 clientHeight 高度 则是网页的实际高度
- 一般来说,document.body.clientHeight 大于 document.documentElement.clientHeight
- Element.clientWidth
- Element.clientLeft
- 元素节点左边框(left border)的宽度(单位像素)
- 如果没有设置左边框,或者是行内元素(display: inline),该属性返回 0
- 总是返回整数值,如果是小数,会四舍五入
- Element.clientLeft
- Element.clientTop
- 网页元素顶部边框的宽度(单位像素)
- 如果没有设置左边框,或者是行内元素(display: inline),该属性返回 0
- 总是返回整数值,如果是小数,会四舍五入
- Element.clientTop
- Element.scrollHeight
- 返回一个整数值(小数会四舍五入),表示当前元素的总高度(单位像素),包括溢出容器、当前不可见的部分
- 包括 padding,,还包括伪元素(::before或::after)的高度
- 但是不包括 border、margin 以及水平滚动条的高度(如果有水平滚动条的话)
- 属性只读
- Element.scrollHeight
- Element.scrollWidth
- 返回一个整数值(小数会四舍五入),表示当前元素的总宽度(单位像素),包括溢出容器、当前不可见的部分
- 包括 padding,,还包括伪元素(::before或::after)的高度
- 但是不包括 border、margin 以及垂直滚动条的高度(如果有垂直滚动条的话)
- 属性只读
- Element.scrollWidth
- Element.scrollLeft
- 当前元素的水平滚动条向右侧滚动的像素数量
- 没有水平滚动条的网页元素,属性总是等于0
- Element.scrollLeft
- Element.scrollTop
- 当前元素的垂直滚动条向下滚动的像素数量
- 没有垂直滚动条的网页元素,属性总是等于0
- Element.scrollTop
- Element.offsetParent
- 返回最近的开启了定位的祖先元素
- 如果某个元素的所有上层节点的 position 属性都是static,则 Element.offsetParent 属性指向 <body> 元素(即使body{position: static;})
- Element.offsetParent
- Element.offsetHeight
- 返回一个整数,表示元素的 CSS 垂直高度(单位像素),包括 content、padding 和 border,以及水平滚动条的高度(如果存在水平滚动条)
- 只读属性
- 如果元素的 CSS 设为不可见(比如display: none;),则返回0
- Element.offsetHeight
- Element.offsetWidth
- 返回一个整数,表示元素的 CSS 水平宽度(单位像素),包括 content、padding 和 border,以及垂直滚动条的宽度(如果存在垂直滚动条)
- 只读属性
- 如果元素的 CSS 设为不可见(比如display: none;),则返回0
- Element.offsetWidth
- Element.offsetLeft
- 返回当前元素左上角相对于 Element.offsetParent 节点的水平位移,单位为像素
- Element.offsetLeft
- Element.offsetTop
- 返回当前元素左上角相对于 Element.offsetParent 节点的垂直位移,单位为像素
-
算出元素相对于整张网页的坐标
// 获取元素 在 网页 中的 坐标 Test Already.
function getElementPosition(ele) {
var left = 0;
var top = 0;
var p = ele;
while (p !== null) {
left += p.offsetLeft;
top += p.offsetTop;
p = p.offsetParent; // 遍历相对元素的坐标
} var pageHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
var pageWidth = Math.max(document.body.scrollWidth, document.documentElement.scrollWidth); return {
left: left,
top: top, right: pageWidth - left - ele.offsetWidth,
bottom: pageHeight - top - ele.offsetHeight
};
}
- Element.offsetTop
- Element.style
- 读写该元素的行内样式信息
- Element.style
- Element.children
- 返回一个类似数组的对象(HTMLCollection实例),包括当前元素节点的所有子元素。
- 如果当前元素没有子元素,则返回的对象包含零个成员
- Element.children
- Element.childElementCount
- 返回当前元素节点包含的子元素节点的个数
- 与 Element.children.length 的值相同
- Element.childElementCount
- Element.firstElementChild
- 返回当前元素的第一个元素子节点
- 如果没有元素子节点,这两个属性返回 null
- Element.firstElementChild
- Element.lastElementChild
- 返回最后一个元素子节点
- 如果没有元素子节点,这两个属性返回 null
- Element.lastElementChild
- 属性相关实例方法
- getAttribute() 读取某个属性的值
- setAttribute() 写入属性值
- hasAttribute() 某个属性是否存在
- hasAttributes() 当前元素是否有属性
- removeAttribute() 删除属性
- getAttributeNames() 返回当前元素的所有属性名
- 其他实例方法
- Element.querySelector()
- 接受 CSS 选择器作为参数,返回父元素的第一个匹配的子元素。
- 如果没有找到匹配的子元素,就返回 null
- 注意,这个方法无法选中伪元素
- 多个选择器,它们之间使用逗号分隔
- Element.querySelector()
- Element.querySelectorAll()
- 接受 CSS 选择器作为参数,返回一个 NodeList 实例,包含所有匹配的子元素
- Element.querySelectorAll()
- Element.closest()
- 接受一个 CSS 选择器作为参数,返回匹配该选择器的、最接近当前节点的一个祖先节点(包括当前节点本身)。
- 如果没有任何节点匹配 CSS 选择器,则返回 null
// HTML 代码如下
// <article>
// <div id="div-01">Here is div-01
// <div id="div-02">Here is div-02
// <div id="div-03">Here is div-03</div>
// </div>
// </div>
// </article> var div03 = document.getElementById('div-03'); // div-03 最近的祖先节点
div03.closest("#div-02") // div-02
div03.closest("div div") // div-03
div03.closest("article > div") //div-01
div03.closest(":not(div)") // article
- Element.closest()
-
事件相关方法
- Element.addEventListener()
- 添加事件的回调函数
- Element.addEventListener()
- Element.removeEventListener()
- 移除事件监听函数
- Element.removeEventListener()
- Element.dispatchEvent()
-
触发事件
element.addEventListener('click', listener, false);
element.removeEventListener('click', listener, false); var event = new Event('click');
element.dispatchEvent(event);
-
触发事件
- Element.dispatchEvent()
- Element.scrollIntoView()
- 滚动当前元素,进入浏览器的可见区域,类似于设置 window.location.hash 的效果
el.scrollIntoView(); // 等同于el.scrollIntoView(true)
el.scrollIntoView(false); // 如果为true,表示元素的顶部与当前区域的可见部分的顶部对齐(前提是当前区域可滚动)
// 如果为false,表示元素的底部与当前区域的可见部分的尾部对齐(前提是当前区域可滚动)
// 如果没有提供该参数,默认为true
- Element.scrollIntoView()
- Element.getBoundingClientRect()
- 返回一个对象,提供当前元素节点的大小、位置等信息,基本上就是 CSS 盒状模型的所有信息
- 属性全部为只读
- 对于视口(viewport)的位置,会随着页面滚动变化,因此表示位置的四个属性值是动态的
x // 元素左上角相对于视口的横坐标
y // 元素左上角相对于视口的纵坐标
height // 元素高度
width // 元素宽度
left // 元素左上角相对于视口的横坐标,与x属性相等
right // 元素右边界相对于视口的横坐标(等于x + width)
top // 元素顶部相对于视口的纵坐标,与y属性相等
bottom // 元素底部相对于视口的纵坐标(等于y + height)都把边框(border属性)算作元素的一部分。
也就是说,都是从边框外缘的各个点来计算。
因此,width和height包括了元素本身 + padding + border
- Element.getBoundingClientRect()
- Element.getClientRects()
- 返回一个类似数组的对象,里面是当前元素在页面上形成的所有矩形
- Element.getClientRects()
- Element.insertAdjacentElement()
- 在相对于当前元素的指定位置,插入一个新的节点
- 返回新插入的节点,如果插入失败,返回 null
- 第一个参数是一个字符串,表示插入的位置
- Element.insertAdjacentElement()
- beforebegin 当前元素之前,只在当前节点有父节点时才会生效
- afterbegin 当前元素内部的第一个子节点前面
- beforeend 当前元素内部的最后一个子节点后面
- afterend 当前元素之后,只在当前节点有父节点时才会生效
- 第二个参数是将要插入的节点
- Element.insertAdjacentHTML(position, text);
- 用于将一个字符串,解析生成 HTML DOM 结构,插入相对于当前节点的指定位置
- beforebegin 当前元素之前,只在当前节点有父节点时才会生效
- afterbegin 当前元素内部的第一个子节点前面
- beforeend 当前元素内部的最后一个子节点后面
- afterend 当前元素之后,只在当前节点有父节点时才会生效
- 用于将一个字符串,解析生成 HTML DOM 结构,插入相对于当前节点的指定位置
- Element.insertAdjacentHTML(position, text);
- Element.insertAdjacentText()
- 在相对于当前节点的指定位置,插入一个文本节点,用法与Element.insertAdjacentHTML() 方法完全一致
- Element.insertAdjacentText()
- Element.remove()
- 继承自 ChildNode 接口,用于将当前元素节点从它的父节点移除
-
var el = document.getElementById('mydiv');
el.remove();将 el 节点从 DOM 树里面移除
-
- 继承自 ChildNode 接口,用于将当前元素节点从它的父节点移除
- Element.remove()
- Element.focus()
- 将当前页面的焦点,转移到当前元素上
- 可以接受一个对象作为参数
- 参数对象的preventScroll属性是一个布尔值,指定是否将当前元素停留在原始位置,而不是滚动到可见区域
document.getElementById('my-span').focus(); function getFocus() {
document.getElementById('btn').focus({preventScroll:false}); // 让btn
元素 获得焦点,并滚动到可见区域。
}
- Element.focus()
- Element.blur()
- 用于将焦点从当前元素移除
- Element.blur()
- Element.click()
- 用于在当前元素上模拟一次鼠标点击,相当于触发了 click 事件
- Element.click()