选取文档元素的API


除了现在常用的选取API
1 document.getElementById()
2 document.getElementsByName()
3 document.getElementsByTagName()
4 ...

 新增的API 主要是
  document.querySelector('div>ul')
  document.querySelectorAll('div>ul>li')
     这两个API的强大之处在于能像CSS选择器一样选择元素,和Jquery的选择器有的一拼

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div>
<ul>
<li></li>
<li class="abc"></li>
<li class="bbb abc"></li>
</ul>
</div>
<div>
<p>11111111111111
</p>
</div>
</body>
<script>
var a=document.querySelectorAll('div>ul')[0]
console.log(a.childElementCount) // 3
var b=document.createElement('li');
b.textContent='44444';
a.appendChild(b)
    console.log(a.childElementCount) //3
console.log(document.querySelectorAll('div>ul>li').length) //4
</script>
</html>


以下介绍下他们的不同点:
    document.querySelector()
        返回的是第一个匹配的元素(以文档顺序)
        匹配不到则返回null
   document.querySelectorAll()
       返回的是一个表示文档中匹配选择器的所有元素的NodeList对象(显然该对象是一个集合),
       这个NodeList对象并不是实时的:它包含在调用时刻选择器锁匹配的元素,但并不更新后续文档的变化(详见上面实列)
       匹配不到则返回一个空的NodeList对象
      选择器非法 将抛出异常
另外一点是这两个方法在Element节点中也有定义 (DocumentFragment节点上也是有定义的)
如:

     var d=document.getElementsByTagName('div')[0].querySelector('.abc')
     console.log(d.textContent)

目前支持这两个API 有:IE8+,Firefox 3.5+,Safari 3.1+,Chrom 和Opera 10+

有一个小问题:
    <div id="abcdefg">
                <p>11111111111111
               </p>
    </div>
     var c=document.querySelector('#abcdefg');
     console.log(c.querySelector('div p').innerHTML); // 这个是能找到值的
   理想情况是 在id为abcdefg 的内部查找 div 下面的p元素,显示出p的innerHTML 应该是找不到的
   但是现在却打印出来了 It's a problem; 查询时也必要这样查询
   应该一次性写出来: document.querySelector('#abcdefg div p'); 会报异常 因为找不到

 

性能问题:

       通过对1千万次的读取发现getElementBy系列的查询速度要远高与 queryselector系列

 

 1  var begin = new Date();
 2     for (var i = 0; i < 10000000; i++) {
 3 
 4         var a=document.getElementById('abc');
 5 
 6     }
 7     var end= new Date();
 8     console.log(end-begin);
 9     var begin1 = new Date();
10     for (var i = 0; i < 10000000; i++) {
11 
12         var a=document.querySelector('#abc');
13 
14     }
15     var end1=new  Date();
16     console.log(end1-begin1);

   究其原因发现 主要是因为queryselectorall  返回的nodeList是静态的 而getElementBy 系列返回的是动态的  细化一下主要是:

         在深入了解细节之前,首先说下这俩个方法重要的区别,不仅仅是一个方法接受tagName,另外一个接受css选择器。最重要的区别在于返回值: getElementsByTagName() 返回一个实时的 NodeList,
querySelectorAll()返回静态的 NodeList。 这点是对理解速度的快慢是非常重要的。实时的NodeList 这个是文档对象模型(Document Object Model)的一个坑。 NodeList对象(也就是在HTML DOM中的HTMLCollection对象)是个特殊的类型。DOM3手册对HTMLCollection对象的规定如下:

        Nodelist跟NamedNodeMap对象在DOM中是实时的;也就是说,对基本文档结构的修改,会被映射到相关的Nodelist跟NameNodeMap对象。例如,如果一个DOM的用户得到了包含有子元素节点的NodeList对象,随后在这个元素上添加更多的子节点(或者是移除,或者是修改他们),这些改变会自动映射到NodeList对象中,不需要用户部分的额外操作。同样的,改变在树中的节点,也会自动映射到跟这个节点有关的
NodeList跟NamedNodeMap中的对象。
getElementsByTagName()方法,返回这些实时的元素集合-随着文档的改变而更新。因此,下边这段代码其实是个死循环:

 1 var divs = document.getElementsByTagName("div"),
 2 i=0;
 3 while(i < divs.length){
 4 document.body.appendChild(document.createElement("div"));
 5 i++;
 6 }

因为divs.lenght实时计算的原因,所以这是个死循环。每次迭代,添加一个新的div,意味着divs.length每次循环都会增加。

这些实时的集合,看起来像个坏主意,但是他们被放到document.images,document.forms这些方法中,跟其他的一些pre-DOM的集合中使用相同的对象,在浏览器中非常常见。

  静态的NodeList
        querySelectorAll()返回的是静态的NodeList,描述如下:被querySelectorAll() 返回的对象必须(must)是静态的,非实时的([DOM-LEVEL-3-CORE],1.1.1部分)。后来的对文档的改变,不能(must not)反应到NodeList对象上。这意味着,此对象实际上包含的是文档刚创建的时候,查询到的匹配的列表。所以,即使querySelectorAll()的返回值跟表现,同getElementsByTagName()是一样的,但是实际上,他们是不同的。在前者中,NodeList实际上是一个文档状态,在方法被调用时刻的快照,后者总是会更新到当前的状态。所以,下边的代码不是死循环:

 1 var divs = document.querySelectorAll("div"),
 2 i=0;
 3 while(i < divs.length){
 4 document.body.appendChild(document.createElement("div"));
 5 i++;
 6 }

div.length 不会改变。

   So为啥是实时的NodeLists更快呢?
       实时的NodeLit对象能够快速的被浏览器创建,并返回,因为他们他们不必知道从开始到现在的数据信息,但是,静态的需要收集这些信息。再此强调下,WebKit的源码对两中类型的NodeList有独立的文件:DynamicNodeList.css跟StaticNodeList.cspp.两种类型的对象以不同的方式被创建。DynamicNodelist是被注册到缓存中。本质上,创建DynamicNodelist开销是比较小的,因为他不会之前的事情。无论何时DynamicNodeList被访问的时候,它必须查询文档的改变,作为length属性跟item()方法的结果跟StaticNodeList比较,在另外一个文件中实例被创建,然后用内部的一个循环,进行数据填充。之前文档查询的开销比使用”DynamicNodeList”实例大的多。如果你看一下WebKit的源码,创建querySelectorAll()的返回值的时候,都是使用循环去创建这个结果。

  结论:
     getElementsByTagName()比querySelectorAll()快的原因是,实时跟静态NodeList对象引起的。
     决定使用哪个方法,主要取决于你想要什么。如果你通过tagName搜索元素,不需要快照,应该使用getElementsByTagName();如果你需要一个快照结果,或者是做一个更复杂的css查询,应当使用
**querySelectorAll()*

    注,部分文档摘录自:

      http://www.cnblogs.com/dolphinX/p/3354318.html

        http://www.heyria.com/index.php/2014/06/why-is-getelementsbytagname-faster-that-queryselectorall/

 

 
 




 



     

  

转载于:https://www.cnblogs.com/ArthurXml/p/5387637.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/357338.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue进阶

1、vue-cli 使用 在开发中&#xff0c;需要打包的东西不止是js、css、html。还有更多的东西要处理&#xff0c;这些插件和加载器如果我们一一去添加就会比较麻烦&#xff0c;vue官方提供了一个快速搭建vue项目的脚手架&#xff0c;使用它能快速的构建一个web工程模板。 官网&…

每天一个linux命令(1):ln 命令

每天一个linux命令&#xff08;35&#xff09;&#xff1a;ln 命令 ln 是linux中又一个非常重要命令&#xff0c;它的功能是为某一个文件在另外一个位置建立一个同步的链接.当我们需要在不同的目录&#xff0c;用到相同的文件时&#xff0c;我们不需要在 每一个需要的目录下都放…

ehcache 程序_将Ehcache添加到Openxava应用程序

ehcache 程序介绍 本文介绍如何在Openxava应用程序上快速启用Ehcache&#xff0c;从而提高性能。 查看实体及其图形时&#xff0c;将加载关系。 添加第二级缓存可加快关联元素的检索速度&#xff0c;因为已加载的元素是从缓存而不是数据库中检索的。 最终&#xff0c;该页面解…

Diff 算法核心原理

什么是虚拟DOM 讲Diff算法前&#xff0c;我先给大家讲一讲什么是虚拟DOM吧。这有利于后面大家对Diff算法的理解加深。 虚拟DOM是一个对象&#xff0c;一个什么样的对象呢&#xff1f;一个用来表示真实DOM的对象&#xff0c;要记住这句话。我举个例子&#xff0c;请看以下真实…

比较Java 8中的命令式和功能性算法

Mario Fusco的流行推文令人印象深刻&#xff0c;显示了类似算法的命令性和功能性方法之间的主要区别实际上是&#xff1a; 势在必行–功能分离pic.twitter.com/G2cC6iBkDJ — Mario Fusco&#xff08;mariofusco&#xff09; 2015年3月1日 两种算法都做同样的事情&#xff0…

mvc的视图中显示DataTable的方法

mvc的视图中显示DataTable的方法&#xff1a; 不断的循环画出table {ViewBag.Title "ShowDataTable"; } using System.Data; model Models.ConModel{var table Model.ExcelTable as DataTable; }<script src"~/Scripts/My97DatePicker/WdatePicker.js"…

rem,em,px,rpx等

1、任意浏览器的默认字体高都是16px。谷歌浏览器显示的最小字体大小是12px。 exp&#xff1a;突破谷歌浏览器显示12px限制。 &#xff08;1&#xff09;、<div>文本</div> 文本嵌套块标签&#xff0c;这是因为缩放只对有宽高的标签有效&#xff0c;缩放的时候也是…

python 列表 字典 读写文件:pickle模块的基本使用

建议大家使用cPickle&#xff0c;速度更快&#xff01;&#xff01;&#xff01; python数据持久存储&#xff1a;pickle模块的基本使用&#xff08;转载&#xff09; 作者: pzxbc出处: http://pzxbc.cnblogs.com/本文版权归作者和博客园共有&#xff0c;欢迎转载&#xff0c;但…

first-child、first-of-type等属性的差别

1、xxx:first-child 伪类 xxx作为第一个子元素 //p元素作为第一个子元素的都会变色 p:first-child { background:yellow; } //p作为父元素的 第一个子元素。不要求第一个元素的类型 p>:first-child {background:yellow; }//p作为父元素的 第一个子元素。要求第一个元素的类…

js 手机端触发事事件、javascript手机端/移动端触发事件

处理Touch事件能让你跟踪用户的每一根手指的位置。你可以绑定以下四种Touch事件: touchstart: // 手指放到屏幕上的时候触发 touchmove: // 手指在屏幕上移动的时候触发 touchend: // 手指从屏幕上拿起的时候触发 touchcancel: // 系统取消touch事件的时候触发。至于系统…

java 8 lambda_Java 8的烹调方式– Lambda项目

java 8 lambda什么是project lambda &#xff1a;Project lambda是用于以Java语言语法启用lambda表达式的项目。 Lambda表达式是功能编程语言&#xff08;如lisp&#xff09;中的主要语法。 Groovy将是支持lambda表达式&#xff08;也称为闭包&#xff09;的java的最接近亲戚。…

我的Serverless实战——引领云计算的下一个十年

前言&#xff1a;如今&#xff0c;越来越多的大厂企业开始大规模使用Serverless&#xff0c;处于变革中的开发者&#xff0c;大多已从观望状态转向尝试阶段&#xff0c;越来越多Serverless落地场景被解锁。作为基础研发底座&#xff0c;越来越多企业开始接受Serverless&#xf…

各种边距clientWidth、offsetWidth、scrollWidth、clientLeft、getBoundingClientRect详解

1、clientWidth、offsetWidth、scrollWidth <!DOCTYPE html> <html><head><meta charset"utf-8" /><style>#box1 {padding: 50px;position: static;}#box {border: 1px solid red;overflow: scroll;height: 200px;width: 500px;}#con…

encodeURIComponent的使用

URL 元字符&#xff1a;分号&#xff08;;&#xff09;&#xff0c;逗号&#xff08;,&#xff09;&#xff0c;斜杠&#xff08;/&#xff09;&#xff0c;问号&#xff08;?&#xff09;&#xff0c;冒号&#xff08;:&#xff09;&#xff0c;at&#xff08;&#xff09;&a…

如何以及何时使用枚举和注释

本文是我们名为“ 高级Java ”的学院课程的一部分。 本课程旨在帮助您最有效地使用Java。 它讨论了高级主题&#xff0c;包括对象创建&#xff0c;并发&#xff0c;序列化&#xff0c;反射等。 它将指导您完成Java掌握的过程&#xff01; 在这里查看 &#xff01; 目录 1.简…

花了两天时间用html+css+js做了一个网页版坦克大战游戏

大家好&#xff0c;我是孙叫兽&#xff0c;本期内容给大家分享如何用htmlcssjavaScript去做一个简易网页版坦克游戏。 目录 坦克游戏玩法及介绍 项目结构 源码地址&#xff1a; 坦克游戏玩法及介绍 我们先来看一下首页。 打开这个首页很简单&#xff0c;基本是上面这个样子&…

软件工程第一次冲刺进度条(1-10天)

第一天&#xff08;4.20&#xff09;昨天做了什么今天做了什么遇到的问题配置安装所需要的环境和相关软件 查询android关于界面编程与视图的相关资料并且初步编写代码 配置虚拟机的时候电脑上总是失败第二天&#xff08;4.21&#xff09;昨天做了什么今天做了什么遇到的问题查询…

css基础过渡与动画与应用于vue、react

一、css属性过渡transition 1、解释&#xff1a; 使用该属性后变化不会在一瞬间完成&#xff0c;会有一个连续的变化效果。第一个参数设置哪些属性变化时需要有连续的效果。 不论用什么方式使属性的值发生变化&#xff0c;transition都会生效。 2、语法&#xff1a; trans…

Android项目开发填坑记-Fragment的onAttach

背景 现在Android开发多使用一个Activity管理多个Fragment进行开发&#xff0c;不免需要两者相互传递数据&#xff0c;一般是给Fragment添加回调接口&#xff0c;让Activity继承并实现。 回调接口一般都写在Fragment的onAttach()方法中&#xff0c;Fragment 3.0 的onAttach()方…

前端开发——移动端及响应式布局解决办法总结(适配)

问题分析:前端开发一个产品(网站、系统、APP等)会遇到的一个难点就是适配问题,比如开发一个网站,你在一个页面开发的时候从视觉看起来没什么异样,换个不同分别率的设备,电脑,手机等,发现样式全乱了,这个不是我们想要的结果,所以,浏览器适配,响应式布局就显得尤为重…