讲DOM之前,说说对象分类
首先JS对象其实目前有好几种分法,但是主流分法中不管是哪一种,DOM都常被认为是宿主对象。其中一种分法就是将JS对象分为三种:
内部对象、宿主对象、自定义对象
内部对象:Array、Boolean、Date、Function、Global、Math、Error….
宿主对象:运行JS脚本环境提供的对象,包含window、document、FormDate、XMLHttpRequest…
自定义对象:就是自己定义的对象
首先window对应着BOM对象相关的知识,document对应着DOM相关的知识,DOM是文档对象模型。但是其实DOM是隶属于BOM的,只是我们经常把DOM专门拿出来说
document方法
首先document是一个对象,从JS的角度来说它代表了一个文档本身,他是所有文档节点的最顶端
那么document上既然是对象就会有相关的方法和属性,我们这一节主要说它的方法。
getElementById/getElementByTagName等
1. document.getElementById('box');//在IE8及以下是不分大小写的,而且在IE8及以下你元素上如果设置了name特性也为box,没有id特性,用该方法是拿得到的
2. document.getElementsByClassName('box1');//IE8及以下用不了
3. document.getElementByTagName('div')//兼容性很好,都兼容
4. document.getElementByName();//用得非常少
复制代码
首先说明,像id特性能不设置就不要设置,模块化开发时id常用于后端向前端注入数据,id一般在前端中叫做钩子
这些方法中,只有getElementById()返回的是元素,其他的方法返回的都是类数组
querySelector/querySelectorAll
这是HTML5规范中新写入的WEB API(但其实很早以前就有了,只是没纳入规范,早有所以兼容性很好)
var div1 = document.querySelector('div');
var div2 = document.querySelector('.text');
var div3 = document.querySelector('div p');
var div4 = document.querySelector('div > p');
var div5 = document.querySelector('#box');
复制代码
我们从使用方法上可以看出()中的选择元素的写法是和css选择器一样的,而且这个方法如果选择到多个元素只会返回选择到的第一个元素
如果我们想获得多个元素可以选择使用document.querySelectorAll
var div1 = document.querySelectorAll(‘.box’);
这样会返回一个包含元素节点的类数组,即使你想获取的是有id特性的元素,也是返回类数组
那么这两个方法兼容性那么好,选择方法还和css很像,那为啥我们很少用这个方法,因为有两个缺点:
1. 性能不好
2. 不是实时的,或者说不是返回值是静态的一旦初始值确定就不会改变
例如:
var divs = document.querySelectorAll('div');
console.log(divs);//[div, div, div]
divs[0].remove();
console.log(divs);//[div, div, div] 不是实时的
复制代码
元素节点树
首先值得注意的是:节点树并不等于元素节点树,而是包含元素节点树
访问节点document上有方法(兼容性比较好),访问元素节点document也有单独的方法。
访问节点(所有节点类型)的属性
访问节点的方法常用的有parentNode/childNodes、firstChild/lastChild、 previousSibling/nextSibling
parentNode(父节点)
在编辑器中写相应代码:
<ul>
<li>
<h2>我是标题标签</h2>
<a href="">我是超链接标签</a>
<p>我是段落标签</p>
</li>
</ul>
复制代码
var a=document.getElementsByTageName('a')[0];
复制代码
在浏览器控制台输入如下代码会得到如下结果:
从以下现象中可以看出,document就是所有文档节点的最顶端
childNodes(子节点)
在编辑器中写相应代码:
<ul>
<li>
<!--这是个注释-->
<h2>我是标题标签</h2>
<a href="">我是超链接标签</a>
<p>我是段落标签</p>
</li>
</ul>
复制代码
var li=document.getElementsByTageName('li')[0];
console.log(li.childNodes.length);
复制代码
控制台输出结果为:
这也侧面说明了节点不仅仅是只有元素节点,也有其他节点
其中节点类型可以用数字来表示:
1.元素节点 === 1
2.属性节点 === 2
3.文本节点(text) === 3
4.注释节点(comment) === 8
5.document === 9
6.DocumentFragment === 11
firstChild/lastChild(第一个/最后一个节点)
还是上面的HTML代码,然后js代码如下:
var li = document.getElementsByTagName('li')[0];
console.log(li.lastChild); //#text
复制代码
元素内第一个节点/元素内最后一个节点 原理与上方一致
nextSibling/previousSibing
var p=document.getElementsByTageName('p')[0];
console.log(p.previousSibling);//#text
复制代码
元素自身的上一个节点/元素的下一个节点 原理与上方一致
获取元素节点的属性
获取元素节点的属性一般有:parentElement/children、 firstElementChild/lastElementChild、nextElementSibing/previousElementSibing
parentElement(父元素节点,IE9及以下不支持)
文档中的元素节点的顶端是html元素
children(子元素节点,IE7及以下不支持)
<div class="div1">
<p>这是第一个p标签</p>
<p class="div2">这是第二个p标签</p>
<span>这是一个span</span>
</div>
复制代码
var div1 = document.getElementsByClassName('div1')[0];
console.log(div1.children);
复制代码
结果为:
firstElementChild/lastElementChild(IE9及以下不支持)
还是前面的HTML代码,为了查看firstElementChild, js修改代码如下:
var div1 = document.getElementsByClassName('div1')[0];
console.log(div1.firstElementChild);
复制代码
结果是:
还是前面的HTML代码,为了查看lastElementChild, js修改代码如下:
var div1 = document.getElementsByClassName('div1')[0];
console.log(div1.lastElementChild);
复制代码
结果是:
nextElementSibling/previousElementSibling(IE9及以下不支持)
还是前面的HTML代码,为了查看nextElementSibling, js修改代码如下:
var p = document.getElementsByClassName('p2')[0];
console.log(p.nextElementSibling);
复制代码
结果如下:
还是前面的HTML代码,为了查看previousElementSibling, js修改代码如下:
var p = document.getElementsByClassName('p2')[0];
console.log(p.previousElementSibling);
复制代码
结果如下:
简要总结
DOM是文档对象模型,是JS对象中的宿主对象,DOM与document相关,document常见的相关方法有
document.getElementById、document.getElementsByClassName、 document.getElementsByTagName、document.getElementsByName
- document.getElementById方法括号内获取元素的元素名在IE8及以下是不分大小写的,而且在IE8及以下你元素上如果设置了name特性也为box,没有id特性,用该方法是拿得到的。
- document.getElementsByClassName方法IE8及以下用不了
- document.getElementByTagName兼容性很好,都兼容
- document.getElementByName用得非常少
节点包含元素节点与其他节点,获取各种类型节点的属性有parentNode/childNodes、firstChild/lastChild、nextSibling/previousSibling,兼容性都很好
获取元素节点的属性有parentElement(IE9及以下不支持)、children(IE7及以下不支持)、 firstElementChild/lastElementChild(IE9及以下不支持)、nextElementSibing/previousElementSibing(IE9及以下不支持)