`
zhouyrt
  • 浏览: 1141686 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Element下querySelector和querySelectorAll的错误实现

    博客分类:
  • BUG
阅读更多

querySelector和querySelectorAll是W3C提供的 新的查询接口


module dom {
  [Supplemental, NoInterfaceObject]
  interface NodeSelector {
    Element   querySelector(in DOMString selectors);
    NodeList  querySelectorAll(in DOMString selectors);
  };
  Document implements NodeSelector;
  DocumentFragment implements NodeSelector;
  Element implements NodeSelector;
};


 

从接口定义可以看到Document、DocumentFragment、Element都实现了NodeSelector接口。即这三种类型的元素都拥有者两个方法。querySelector和querySelectorAll的参数须是符合 css selector 的字符串。不同的是querySelector返回的是一个对象,querySelectorAll返回的一个集合(NodeList)。

目前 IE8/9及Firefox/Chrome/Safari/Opera 的最新版已经支持它们。

如想获取页面class属性为"red"的元素,除了使用document.getElementsByClassName('red')还可以使用document.querySelector('.red')和document.querySelectorAll('.red')。

但Element.querySelector和Element.querySelectorAll的实现有错误,如下

<div id="d1">
	<p><a href="http://www.sina.com.cn">SINA</a></p>
</div>
<script type="text/javascript">	
	function $(id){return document.getElementById(id);}
	var d1 = $('d1');
	var obj1 = d1.querySelector('div a');
	var obj2 = d1.querySelectorAll('div a');
	alert(obj1); // -> http://www.sina.com.cn/
	alert(obj2.length); // -> 1	
</script>

 

在支持这两个方法的浏览器可以看到分别弹出了“http://www.sina.com.cn/”,和 “1”。说明查询到了想要的元素或元素集合。这与W3C的定义却是不合的,根据定义应该是在元素d1范围内查找"div a",而d1内压根没有div。因此应该分别返回null,空集合。

jQuery1.4.2 及之前版本中只使用了document.querySelectorAll,没有使用Element.querySelectorAll。新发布的 jQuery1.4.3 中使用了Element.querySelectorAll,但做了修复。在选择器前加了"#__sizzle__"以强制其在指定元素内查找(3903-3918行)。简化如下

function $(id){return document.getElementById(id);}
var d1 = $('d1');
var obj1 = d1.querySelector('div a');
var obj2 = d1.querySelectorAll('div a');
var old = d1.id, id = d1.id = "__sizzle__";
try {
	var query = '#' + id + ' div a';
	alert(d1.querySelector( query ));
	alert(d1.querySelectorAll( query ).length);
} catch(e) {
} finally {
	old ? d1.id = old : d1.removeAttribute( "id" );
}

 

实现很巧妙,指定范围的元素如果有id,将其保留在old,"__sizzle__"赋值其作为临时id,在选择器"div a"前指定查找范围为"#__sizzle__",即d1。finally语句来最后清理,如果指定范围的元素本身有id将其恢复为old,没有则去掉临时的id属性"__sizzle__"。

 

相关:

http://msdn.microsoft.com/en-us/library/cc288169%28v=VS.85%29.aspx
http://msdn.microsoft.com/en-us/library/cc304115%28VS.85%29.aspx

https://developer.mozilla.org/En/DOM/Document.querySelector

https://developer.mozilla.org/En/DOM/Document.querySelectorAll

https://developer.mozilla.org/En/DOM/element.querySelector

https://developer.mozilla.org/En/DOM/Element.querySelectorAll

 

 

分享到:
评论
2 楼 pfans 2010-11-09  
顶楼书,学习了。
1 楼 lixinlixin2008 2010-11-08  
沙发,学习~~~

相关推荐

    各浏览器中querySelector和querySelectorAll的实现差异分析

    querySelector和querySelectorAll是W3C提供的新的查询接口 querySelector和querySelectorAll是W3C提供的 新的查询接口,其主要特点如下: 1、querySelector只返回匹配的第一个元素,如果没有匹配项,返回null。 2、...

    再谈querySelector和querySelectorAll的区别与联系

    `querySelector` 和 `querySelectorAll` 是在Web开发中用于选取HTML或XML文档中特定元素的JavaScript API,它们都基于CSS选择器。这两个方法都定义在DOM接口中,可以在任何支持这些方法的DOM节点上使用。 **...

    javascript高级选择器querySelector和querySelectorAll全面解析

    querySelector 和 querySelectorAll 方法是 W3C Selectors API 规范中定义的。他们的作用是根据 CSS 选择器规范,便捷定位文档中指定元素。 目前几乎主流浏览器均支持了他们。包括 IE8(含) 以上版本、 Firefox、 ...

    原生的强大DOM选择器querySelector.pdf

    虽然querySelector和querySelectorAll非常实用,但它们并非在所有情况下都比其他DOM操作方法快。在某些场景下,尤其是当需要处理大量元素时,jQuery或其他库的优化过的实现可能会更快。然而,由于它们直接使用原生的...

    javascript之querySelector和querySelectorAll使用介绍

    一开始很多人都会拿jquery的选择器来跟这两个api做对比(我也是),比较异同本来没事,但却使一些同学对这两个api在浏览器中的实现产生了误解,特别是再dom element上调用此api时。 下面是我的jsFiddle示例,我就...

    javascript之querySelector和querySelectorAll使用说明

    一开始很多人都会拿jquery的选择器来跟这两个api做对比(我也是),比较异同本来没事,但却使一些同学对这两个api在浏览器中的实现产生了误解,特别是再dom element上调用此api时。 下面是我的jsFiddle示例,我就...

    原生的强大DOM选择器querySelector介绍

    总的来说,querySelector和querySelectorAll是JavaScript中处理DOM查询的强大工具,它们的灵活性和易用性使得代码更加简洁,提升了开发效率。了解并熟练使用这两个方法,对于任何前端开发者都是必要的技能。

    jQuery选择器querySelector的使用指南

    总的来说,`document.querySelector`和`document.querySelectorAll`为JavaScript提供了与jQuery类似的强大功能,让原生JavaScript代码更加简洁和高效。这两个方法不仅减少了对jQuery库的依赖,而且在某些情况下,...

    前端小工具 - js模拟键盘、鼠标事件给element form批量赋值

    let option = element.querySelector('option[value="新选中值"]'); if (option) { option.selected = true; element.dispatchEvent(new Event('change')); } break; } }); ``` 通过结合以上方法,我们可以...

    js querySelector() 使用方法

    这个方法在处理单个元素时非常有用,因为`querySelector()`只会返回匹配选择器的第一个元素,而不是像`querySelectorAll()`那样返回一个包含所有匹配元素的NodeList。 **基本语法**: ```javascript document....

    elementPresence:仅在页面中找到元素时才运行代码

    ElementPresence V1.0 ... 作为参数,您可以使用通常与querySelector和querySelectorAll一起使用的任何有效选择器。 elementPresence('.element-class').then( ( element ) =&gt; { myOtherFunction() });

    js 常用的webapi

    querySelector 和 querySelectorAll `querySelector` 方法可以用来获取选择器第一个事件源,例如: `let element = document.querySelector('.btn');` `querySelectorAll` 方法可以用来获取选择器所有事件源,...

    JS.css代码及教程

    3. **CSS选择器API**:JavaScript提供了querySelector和querySelectorAll方法,可以像CSS选择器一样选取元素。例如: ```javascript var elements = document.querySelectorAll('.myClass'); ``` 4. **CSS3动画...

    XML教程之DOM对象参考手册 chm

    5. **选择节点**:DOM提供了多种方法来选取节点,如getElementsByTagName、getElementById、querySelector和querySelectorAll等。这些方法返回一个NodeList或单个Node对象,可用于进一步的操作。 6. **遍历和修改...

    mui选项卡切换和下拉刷新加载数据列表代码.zip

    这是一款基于mui框架制作的选项卡切换和下拉刷新加载数据列表代码,手机移动端选项卡切换插件,触屏滑动下拉刷新代码。 js代码 [removed][removed] [removed][removed] [removed][removed] [removed] mui....

    18款anime.js文字动画特效.zip

    2. **选择目标元素**:使用CSS选择器或者JavaScript的querySelector或querySelectorAll方法选择你要应用动画的元素。 ```javascript const element = document.querySelector('.your-element'); ``` 3. **定义动画...

    js树形结构实现

    const childrenList = nodeElement.querySelector('.children'); if (childrenList.style.display === 'none') { childrenList.style.display = 'block'; } else { childrenList.style.display = 'none'; } } ...

Global site tag (gtag.js) - Google Analytics