jquery selector $('#names')和$('input#names')的区别

时间:2011-11-05 16:07:18

标签: jquery jquery-selectors

我的html中有一个复选框,如下所示:

<input id="names" name="names" type="checkbox" value="1">One</input>
<input id="names" name="names" type="checkbox" value="2">One</input>
<input id="names" name="names" type="checkbox" value="3">One</input>

我认为$('#names')会让我处理所有复选框元素但不会$('input#names')这样做。

$('#names').length is 1.

$('input#names').length is 3

为什么会有区别? jsfiddle:http://jsfiddle.net/Urbw5/8/

谢谢, 克里斯。

8 个答案:

答案 0 :(得分:4)

一个原因是这不是有效的HTML。 id元素必须是唯一的。所以jQuery给你奇怪的结果并不让我感到惊讶。如果您想要所有“名称”复选框,您可能需要:

$("input[name='names']")

答案 1 :(得分:3)

差异无关紧要,id values must be unique within a document。如果您需要对输入进行分组,则必须使用id之外的其他内容(class经常[over]用于此,但您也可以在结构上执行此操作 - 例如,所有给定容器中的input个元素。)

您所看到的结果差异的原因在于jQuery的选择器引擎(Sizzle)如何优化。如果传入一个简单的基于ID的选择器,Sizzle使用document.getElementById(然后检查它返回的内容是否真正具有id,因为IE8之前的IE中存在错误)。所以它返回一个元素。

但是如果传入像input#names这样的复合选择器,它不会遵循该优化路径并且实际上进行DOM搜索(直接在其自己的代码中,或者如果浏览器通过document.querySelectorAll支持它)。通常,这涉及首先搜索所有匹配元素(例如,所有input元素),然后根据其他限定符过滤列表。因此,在您的测试浏览器上,无论是Sizzle还是浏览器的选择器引擎都不会使该选择器短路,即使它应该知道找到了一个匹配元素,这就是它所需要做的一切。

答案 2 :(得分:3)

$('#names')导致jquery使用显然返回单个元素的getElementById,而$('input#names')将执行类似:getElementsByTagName的操作,然后使用循环查找仅具有id的内容作为names

答案 3 :(得分:2)

input#names搜索ID为names的输入元素 #names会搜索ID为names的任何元素 但是因为你不能在页面中对多个元素使用相同的id,所以这就是问题所在。如果您在页面中需要多次,请使用类 http://jsfiddle.net/FrxN8/

答案 4 :(得分:2)

因为您使用多个ID而发生不一致。

dfinition的ID是唯一的。在给定文档中应该只有一个ID。您不应该使用相同的ID放置许多元素。有一个类名。

另外,在旁注中,<input>元素不应包含任何内容(甚至不包含文本节点)。

<input class="names" name="names" type="checkbox" value="1">
<input class="names" name="names" type="checkbox" value="2">
<input class="names" name="names" type="checkbox" value="3">

然后$('.names').length = 3$('input.names').length = 3

答案 5 :(得分:2)

问题是您的HTML无效。 id值必须在文档中是唯一的。实现此目的的正确方法是使用class代替:

<input class="names" name="names" type="checkbox" value="1">
<input class="names" name="names" type="checkbox" value="2">
<input class="names" name="names" type="checkbox" value="3">

并使用jQuery:

$(".names");

或者,您可以使用属性equals selector按名称选择:

$("input[name='names']");

答案 6 :(得分:1)

正如詹姆斯所说,拥有多个具有相同ID的元素是无效的。这就是name属性的用途。很奇怪你的第二个版本可以工作,但它必须只是jquery中的一个怪癖。

删除id(除非你需要它,在这种情况下确保它们是唯一的)。然后做

('input[name="names"]').length

与大多数人不同,我不建议在这种情况下使用课程。你只是用你不使用的类名膨胀dom。这里的属性选择器完全有效,无需添加您未使用的类。

答案 7 :(得分:1)

詹姆斯是对的,HTML验证只需要使用一次“id”。我的猜测是jQuery被实现为首先停止发现“id”。

另一方面,你正在寻找“输入”标签,所以jQuery知道他可以找到很多标签。但它无论如何都不应该起作用。

改为使用“.names”,每次测试都会获得相同的结果。

修改 顺便说一句,

$(“。names”)将查找具有类“names”的每个标记,而$(“input.names”)将仅查找具有类“names”的输入标记。

希望它有所帮助。