Fork me on GitHub

DOM操作

DOM Element 对象

Document 节点

Document 节点属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
document.doctype //返回当前文档的文档类型
document.documentElement //返回当前文档的根节点
document.defaultView //返回document对象所在的window对象
document.body //返回当前文档的<body>节点
document.head //返回当前文档的<head>节点
document.activeElement //返回当前文档中获得焦点的元素

//节点集合属性
document.links // 返回当前文档的所有a元素
document.forms //返回页面所有表单元素
document.images //返回页面中所有图片元素
document.embeds //返回网页中所有嵌入对象
document.scripts //返回当前文档的所有脚本
document.styleSheets //返回当前网页的所有样式表

//文档信息属性
document.documentURI //表示当前文档的网址
document.URL //返回当前文档的网址
document.domain //返回当前文档的域名
document.lastModified //返回当前文档最后修改的时间戳
document.location //返回location对象,提供当前文档的URL信息
document.referrer //返回当前文档的访问来源
document.title //返回当前文档的标题
document.characterSet //属性返回渲染当前文档的字符集,比如UTF-8、ISO-8859-1。
document.readyState //返回当前文档的状态
document.designMode //控制当前文档是否可编辑,可读写
document.cookie //用来操作Cookie

Document 节点方法

读写方法

1
2
3
4
document.open()   //用于新建并打开一个文档
document.close() //不安比open方法所新建的文档
document.write() //用于向当前文档写入内容
document.writeIn() //用于向当前文档写入内容,尾部添加换行符

节点查找 API

  • document.getElementById('id')
    返回指定 ID 的元素
  • document.getElementsByTagName('tagName')
    返回拥有指定标签名的所有子元素的集合。如果是*,表示查询所有标签
  • document.getElementsByClassName('class')
    返回指定 class 的对象集合
  • document.getElementsByName('name')
    根据元素的 name 属性查找,返回一个 NodeList 。
  • document.querySelector('#id>.class')
    返回第一符合条件的节点
  • document.querySelectorAll('#id>.class')
    返回所有符合条件的节点集合

节点创建 API

  • document.createElement('div') 创建元素

  • document.createTextNode('文本内容') 创建文本节点

  • cloneNode(true/false) 克隆节点,参数表示是否克隆子节点

    1
    2
    3
    4
    const form=document.getElementById('test');
    let clone=form.cloneNode(true)
    clone.id='test2';
    document.body.appendChild(clone)
  • document.createAttribute(name) 生成一个新的属性对象节点,并返回它

  • document.createDocumentFragment() 生成一个 DocumentFragment 对象

事件方法

1
2
3
4
document.createEvent(type)   //生成一个事件对象,该对象能被element.dispatchEvent()方法使用
document.addEventListener(type,listener,capture) //注册事件
document.removeEventListener(type,listener,capture) //注销事件
document.dispatchEvent(event) //触发事件

其他

1
2
3
document.hasFocus()   //返回一个布尔值,表示当前文档之中是否有元素被激活或获得焦点。
document.adoptNode(externalNode) //将某个节点,从其原来所在的文档移除,插入当前文档,并返回插入后的新节点。
document.importNode(externalNode, deep) //从外部文档拷贝指定节点,插入当前文档。

Element 节点

与元素本身特征相关的属性

  1. element.attributes 返回指定节点的属性集合(类数组对象)
  2. element.id 返回指定元素的 id 属性,可读写
  3. element.tagName 返回指定元素的大写标签名
  4. element.innerHTML 设置或返回元素的内容
    如果设置该属性为空,就是删除它包含的所有节点

    1
    el.innerHTML=''
  5. element.tagName 返回指定元素的大写标签名

  6. element.outerHTML 返回指定元素节点的所有 HTML 代码,包括它自身和包含的的所有子元素,可读写
  7. Element.className //返回当前元素的 class 属性,可读写
  8. Element.classList //返回当前元素节点的所有 class 集合
  9. Element.dataset 返回节点 data-开头的属性
1
2
<div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth>John Doe</div>
ele.dataset.id === '1234567890'

查找节点方法

1
2
3
4
Element.querySelector()
Element.querySelectorAll()
Element.getElementsByTagName()
Element.getElementsByClassName()

插入节点 API

  • appendChild 向父节点的最后一个子节点后追加新节点

    1
    parent.appendChild(child)
  • insertBefore 向父节点的某个特定子节点之前插入新节点

    1
    parent.insertBefore(newChild,existingChild)

修改节点 API

  • replaceChild 用新节点替换父节点中已有的子节点

    1
    parent.replaceChild(newChild,existingChild)

删除节点 API

  • removeChild 删除已有节点,返回值为删除节点

    1
    parent.removeChild(existingChild)

节点判断

  • parent.contains(node) 返回 Boolean,表示参数节点是否为当前节点的后代节点
  • Node.isEqualNode(node) 返回 Boolean,用于检查两个节点是否相等,指的是两个节点的类型相同、属性相同、子节点相同
  • Node.normalize() 用于清理当前节点内部的所有 Text 节点。它会去除空的文本节点,并且将毗邻的文本节点合并成一个。

节点属性 API

  • 获取属性

    • Node.nodeName,返回节点名称,只读
    • Node.nodeType,返回节点类型的常数值,只读
    • Node.nodeValue,返回 Text 或 Comment 节点的文本值,只读
    • Node.textContent,返回当前节点和它的所有后代节点的文本内容,可读写
    • Node.baseURI,返回当前网页的绝对路径
    • Node.ownerDocument,返回当前节点所在的顶层文档对象,即 document
  • element.className 设置或返回元素的 class 属性

  • getAttribute 获取节点属性值

    1
    ele.getAttribute('src')
  • setAttribute 修改节点属性,如果属性已存在,则仅设置/更改值。

    1
    ele.setAttribute(attributeName,attributeValue)
  • removeAttribute 删除具有指定属性名称的属性,无返回值

    1
    ele.removeAttribute('属性名')
  • hasAttribute() 元素是否有指定属性,返回 Boolean

    1
    ele.hasAttribute('onclick')

节点关系 API

  1. 父关系

    • parentNode 返回父节点,父节点可能是 Element,Document 或 DocumentFragment;如果没有返回 null

    • parentElement 返回元素的父元素节点,其父节点必须是一个 Element 元素,如果不是,则返回 null;

  2. 子节点

    • children 返回 HTMLCollection,子节点都是 Element,IE9 以下浏览器不支持;
    • childNodes 返回 NodeList,子节点可能包含文本节点、注释节点等
    • firstChild 第一个字节点,不存在返回 null
    • lastChild 最后一个字节点,不存在返回 null
    • Node.firstElementChild //返回当前节点的第一个 Element 子节点
    • Node.lastElementChild //返回当前节点的最后一个 Element 子节点
    • Node.childElementCount //返回当前节点所有 Element 子节点的数目。
  3. 兄弟关系

    • previousSibling 前一个节点,可能包含文本节点、注释节点等

    • nextSibling 后一个节点,可能包含文本节点、注释节点等

    • previousElementSibling 返回前一个元素节点,前一个节点必须是 Element,注意 IE9 以下浏览器不支持。

    • nextElementSibling 返回后一个元素节点,后一个节点必须是 Element,注意 IE9 以下浏览器不支持。

Element 节点的方法

  • Element.getBoundingClientRect()
    位置,返回一个对象,包含 top,left,right,bottom,width,height
    • top 元素上外边界距窗口最上面的距离
    • right 元素右外边界距窗口最上面的距离
    • bottom 元素下外边界距窗口最上面的距离
    • left 元素左外边界距窗口最上面的距离
    • width 元素自身宽(包含 border,padding)
    • height 元素自身高(包含 border,padding)
  • Element.getClientRects()
    返回一个指向客户端中每一个盒子的边界矩形的矩形集合。

元素在页面上的偏移量

1
2
3
4
5
var rect = el.getBoundingClientRect()
return {
top: rect.top + document.body.scrollTop,
left: rect.left + document.body.scrollLeft
}

Element 对象盒状模型属性

  1. element.clientHeight,element.clientWidth
    element.clientHeight:返回元素的可见高度
    element.clientWidth:返回元素的可见宽度
    Element.clientLeft:返回元素节点左边框的宽度
    Element.clientTop:返回元素节点顶部边框的宽度
    包含 padding+CSS 高度
    不包括溢出(overflow)、滚动条、边框、和 margin

    对于整个网页来说,当前可见高度(即视口高度)要从 document.documentElement 对象(即节点)上获取,
    等同于 window.innerHeight-水平滚动条的高度,window.innerWidth-垂直滚动条宽度。
    没有滚动条时两值相等,有滚动条前者小于后者

    视口的高度和宽度(包括滚动条),有两种方法可以获得。
    对于整个网页,基本都不会设置 border,所以只考虑 padding 和滚动条的影响

    1
    2
    3
    4
    5
    6
    7
    // 视口高度
    window.innerHeight // 包括滚动条
    document.documentElement.clientHeight // 不包括滚动条

    // 视口宽度
    window.innerWidth // 包括滚动条
    document.documentElement.clientWidth // 不包括滚动条
  2. element.offsetHeight,element.offsetWidth
    element.offsetHeight:返回元素的高度
    element.offsetWidth:返回元素的宽度
    包含 Padding+Border+滚动条
    如果不存在内容溢出,element.offsetHeight 比 element.clientHeight 多了边框的高度

    整张网页的高度,可以在 document.documentElement 和 document.body 上读取

    1
    2
    3
    4
    5
    6
    //网页总高度
    document.documentElement.offsetHeight
    document.body.offsetHeight
    //网页总宽度
    document.documentElement.offsetWidth
    document.body.offsetWidth
  3. element.offsetLeft,element.offsetTop(可读 像素)
    element.offsetLeft:返回元素左上角相对于 Element.offsetParent 节点的水平偏移位置
    element.offsetTop:返回元素的垂直偏移位置,通常,这两个值指相对于父节点的位移

  4. element.scrollHeight,element.scrollWidth(只读)(像素)
    element.scrollHeight:返回元素的整体高度
    element.scrollWidth:返回元素的整体宽度

    它们返回的是整个元素的高度或宽度,包括由于存在滚动条和不可见的部分。默认情况下,它们包括 Padding,但不包括 Border 和 Margin。

    整张网页的总高度

    1
    2
    document.documentElement.scrollHeight
    document.body.scrollHeight

    如果内容没有溢出,element.scrollHeight=element.clientHeight
    存在溢出时当滚动条到内容底部时,

    1
    element.scrollHeight-element.scrollTop===element.clientHeight //true
  5. element.scrollTop,element.scrollLeft(可读 像素)
    element.scrollTop:返回元素的水平滚动条向右侧滚动的距离
    element.scrollLeft:返回元素水平滚动条向下滚动的距离
    对于那些没有滚动条的网页元素,这两个属性总是等于 0。

    整张网页的水平或垂直滚动距离

    1
    2
    document.documentElement.scrollLeft
    document.documentElement.scrollTop
  6. Element.style 返回元素节点的行内样式

事件方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Element.addEventListener():添加事件的回调函数
Element.removeEventListener():移除事件监听函数
Element.dispatchEvent():触发事件

//ie8
Element.attachEvent(oneventName,listener)
Element.detachEvent(oneventName,listener)

// event对象
var event = window.event||event;

// 事件的目标节点
var target = event.target || event.srcElement;

// 事件代理
ul.addEventListener('click', function(event) {
if (event.target.tagName.toLowerCase() === 'li') {
console.log(event.target.innerHTML)
}
});

通用事件监听方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
const EventUtils = {
//添加事件
addEvent: function (element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false)
} else if (element.attachEvent) {
element.attachEvent('on' + type, handler)

} else {
element['on' + type] = handler
}
},
//移除事件
removeEvent: function (element, type, handler) {
if (element.removeEventListener) {
element.removeEventListener(type, handler)
} else if (element.detachEvent) {
element.detachEvent('on' + type, handler);
} else {
element['on' + type] = handler
}
},
//获取事件目标
getTarget: function (event) {
return event.target || event.srcElement
},
//获取事件目标
getEvent: function (event) {
return event || window.event
},
//阻止事件
stopPropagation: function (event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
},
//取消事件的默认行为
preventDefault: function (event) {
if (event.preventDefault) {
event.preventDefault()
} else {
event.returnValue = false
}
}
}

其他

1
2
3
4
5
6
7
8
9
10
11
Element.scrollIntoView() //滚动当前元素,进入浏览器的可见区域

//解析 HTML 字符串,然后将生成的节点插入 DOM 树的指定位置。
Element.insertAdjacentHTML(where, htmlString);
Element.insertAdjacentHTML('beforeBegin', htmlString); // 在该元素前插入
Element.insertAdjacentHTML('afterBegin', htmlString); // 在该元素第一个子元素前插入
Element.insertAdjacentHTML('beforeEnd', htmlString); // 在该元素最后一个子元素后面插入
Element.insertAdjacentHTML('afterEnd', htmlString); // 在该元素后插入

Element.remove() //用于将当前元素节点从 DOM 中移除
Element.focus() //用于将当前页面的焦点,转移到指定元素上

样式

  1. 直接修改元素的样式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    ele.style.color='red';
    ele.setAttribute('style','')

    element.style.setProperty(propertyName,value) //设置css属性
    element.style.getPropertyValue(property) //获取css属性
    element.style.removeProperty(property) //删除css属性

    操作非内联样式
    //ie8
    element.currentStyle[attrName]
    //ie9+
    window.getComputedStyle(el,null)[attrName]
    window.getComputedStyle(el,null).getPropertyValue(attrName)
    //伪类
    window.getComputedStyle(el,':after')[attrName]
  2. 动态添加样式规则

    1
    2
    3
    var style=document.createElement('style');
    style.innerHTML='body{color:red} #top:hover{background-color: red;color: white;}'
    document.head.appendChild(style)
  3. 类名操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    //ie8以下
    Element.className //获取元素节点的类名
    Element.className += ' ' + newClassName //新增一个类名

    //判断是否有某个类名
    function hasClass(element,className){
    return new RegExp(className,'gi').test(element.className);
    }

    //移除class
    function removeClass(element,className){
    element.className = element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'),'');
    }
    //ie10
    ele.classList.remove('foo','bar');
    ele.classList.add('anotherClass','bar');
    ele.classList.toggle('visible');//存在就去掉,不存在就添加
    ele.classList.toggle('visible',i<10)//根据条件增加、删除属性
    ele.classList.contains('foo');//是否包含属性
    ele.classList.replace('foo','bar');//替换属性
-------------本文结束感谢阅读-------------