获取DOM元素方法小结

在开发中不可避免的需要操作DOM,现在就来总结一下原生的获取DOM的API。

getElementById()

该方法是最常用的通过元素的id属性来获取DOM元素的API,返回一个DOM元素

<body>
    <div id="div">我是div</div>
    <script type="text/javascript">
        var div = document.getElementById("div");
        console.log(div); // 打印一个DOM元素
    </script>    
</body>

getElementById() 只能在HTMLDocument类型的实例(document对象)上调用,并不能在元素上使用该方法。

<body>
    <div id="div">
        我是div
        <p id="p">我是p</p>
    </div>
    <script type="text/javascript">
        var div = document.getElementById("div");
        var p = div.getElementById("p"); // 报错了 div上并没有getElementById方法
    </script>
</body>

其实仔细想来也可以理解,元素具有id属性的值在页面上是唯一的(符合标准的话,写多个相同id也拦不住),所以在document下查找具有该id的元素和在某个元素下查找具有该id的元素是一样的。

getElementsByTagName()

通过标签名获取DOM元素的一个集合,该集合的类型是HTMLCollection,并且该方法可以在DOM元素上调用

<body>
    <div id="div">
        <p>我是p1</p>
        <p>我是p2</p>
    </div>
    <script type="text/javascript">
        var div = document.getElementById("div");
        var pCol = document.getElementsByTagName("p"); // 返回具有两个p元素的HTMLCollection集合
        var pCol1 = div.getElementsByTagName("p"); // 返回具有两个p元素的HTMLCollection集合
    </script>
</body>

关于HTMLCollection:是一个元素的集合,是有生命的会呼吸的,该集合并不是一个快照,一个死的,它是会变化的。与之类似的较为熟悉的集合还有NodeList和NamedNodeMap。

<script type="text/javascript">
    for(var i = 0; i < pCol.length; i++){
        div.appendChild(document.createElement("p"));
    }
</script>

以上代码会出现无限循环。若pCol是当时的一个快照上面的循环应该只循环两次。因为pCol这个HTMLCollection集合是会变化的。当添加一个p元素到div元素中pCol元素集合就增加了一个元素,length也随之增加,这样永远不会满足 i >= pCol.length 的条件,所以出现了无限循环。

而是一个活的会呼吸的集合的不只有HTMLCollection一个,其中较为熟悉的有NodeList和NamedNodeMap。

注:可以使用一个变量存一下pCol.length就不会出现这种情况了。

getElementsByName()

该方法很少用,但是在操作表单的时候还是有用武之处的。通过元素名来获取DOM元素集合(NodeList类型 ),并且只能在document对象上调用

<body>
    <form id="form">
        <input type="radio" name="sex" value="0"/>
        <input type="radio" name="sex" value="1"/>
    </form>
    <script type="text/javascript">
        var input = document.getElementsByName("sex"); // 返回一个NodeList类型的集合有两个input标签
    </script>
</body>

注:高程上说该方法返回的HTMLCollection集合,但是通过chrome,Firefox,Safari测试返回的类型都是NodeList。

querySelector()和querySelectorAll()

querySelector()通过合法的CSS选择器来获取DOM元素(只会获取第一个匹配的元素),如果传入不合法的CSS选择符该方法会报错(包括下面的querySelectorAll()方法也会因为不正确的选择符报错),该方法可以在元素上调用

<body>
    <div id="div">
        <p class="p" name="p">p1</p>
        <p id="p" name="p">p2</p>
    </div>
    <script type="text/javascript">
        var div = document.querySelector("#div"); // 第一个一个id为div的div元素
        var p = document.querySelector("p"); // 第一个一个p元素
        var p1 = div.querySelector("p[name='p']"); // 第一个具有name属性,并且值为p的p元素
    </script>
</body>

querySelectorAll()同样通过合法的CSS选择器来获取元素,只是返回的是所有符合条件的元素,而不是第一个符合条件的元素,所以返回的是一个NodeList类型的DOM元素集合。但是这个NodeList集合和上面所说的活的,会呼吸的NodeList不一样,通过querySelectorAll()方法获取的只是一个快照,并不会动态改变。该方法同样可以在元素上调用

<script type="text/javascript">
    var ps = document.querySelectorAll("p");
    for(var i=0; i<ps.length; i++){
        document.body.appendChild(document.createElement("p"));
    }
</script>

上面只是在body末尾添加了两个p元素,并没有无限循环下去。

getElementsByClassName()

千呼万唤始出来的一个原生API,在这个API出来之前就被各种实现了,当然就性能上来说当然原生的好。

返回一个HTMLCollection的DOM元素集合,并且可以在元素上调用

<body>
    <div id="div">
        <p class="p">p1</p>
        <p class="p">p2</p>
    </div>
    <script type="text/javascript">
        var div = document.getElementById("div");
        var ps = div.getElementsByClassName("p"); // 返回 一个HTMLCollection集合
    </script>
</body>

属性

除了通过以上的方法获取DOM元素或元素集合外还可以通过DOM元素的属性来获取DOM元素和元素集合。

childNodes // NodeList类型
childdren // HTMLCollection类型
firstChild
lastChild
previousSibling
nextSibling
previousElementSibling
nextElementSibling
firstElementChild
lastElementChild

以下集合都是HTMLCollection类型

document.images 所有的img标签集合
document.anchors 所有具有name特性的a标签集合
document.links 所有具有link特性的a标签集合
document.forms 所有form标签集合

NodeList和HTMLCollection的区别

我的理解很简单就是NodeList是节点的集合HTMLCollection是元素节点的集合。NodeList中可能包含HTML元素之外的节点比如文本节点,但是HTMLCollection只会包含HTML元素节点。

HTMLCollection有NamedItem() 方法而NodeList没有

<body>
    <div id="div">
        <p>p1</p>
        <p>p2</p>
        <p>p3</p>
    </div>
    <script type="text/javascript">
        var div = document.querySelector("#div");
        var childs = div.childNodes; // 一个NodeList集合
        console.log(childs);
        for(var i = 0, len = childs.length; i < len; i++){
            console.log(childs[i].nodeType, childs[i].nodeName) // 会打印出 3 “#text” 表示是文本节点
        }
        var children = div.children; // 一个HTMLCollection集合
        console.log(children);
        for(var i = 0, len = children.length; i < len; i++){
            console.log(children[i].nodeType, children[i].nodeName) // 并没有打印出 3 “#text” 只出现了 1 “P” 元素节点
        }
    </script>
</body>

但是上面的结论也有疑惑的地方比如querySelectorAll()只能返回HTML元素,但是他的类型确是NodeList,还有getElementsByName()明显返回的也是HTML元素但是同样类型是NodeList类型。

想进一步了解两者之间的区别和联系可以看看知乎上的这个问题

猜你喜欢

转载自blog.csdn.net/lettertiger/article/details/79735417