find('option [selected]')和find('option')之间的区别.filter('[selected]')

时间:2012-10-30 11:10:32

标签: jquery jquery-selectors html-select

情景:

我有两个jQuery表达式:

/* A */ $('select').find('option[selected]');
/* B */ $('select').find('option').filter('[selected]');

这意味着(假设文档中只有一个select,为简单起见):

  • A :获取select,然后查找具有名为option的属性的所有selected个后代。
  • B :获取select,然后找到所有option个后代,然后按具有名为selected的属性的人进行过滤。

预期行为:

A B 应该会得到相同的结果。

实际行为:

用户在下拉列表中更改了选择后

  • A 会返回选中的{em>默认 option
  • B 会返回选中的{em>新 option

问题:

那他们为什么不同呢?我对CSS选择器的理解是错误的吗?

现场演示:

现场演示 here here

源代码:

HTML

<select>
 <option value='p'>p</option> 
 <option value='q' selected>q</option>
 <option value='r'>r</option> 
 <option value='s'>s</option> 
</select>


<input type='button' value='click me!'/> <br/> 
 ResultA : <span id='ResultA'>
    here
</span> <br/> 
 ResultB : <span id='ResultB'>
    here
</span> <br/> 

的Javascript

function SetResult(ResultObj, ElementObj) {
    ResultObj.text("length=" + ElementObj.length + " " + "val()=" + ElementObj.val());
}

$(function() {
    $('input[type=button]').click(function() {
        var SelectObj = $('select');
        SetResult($("#ResultA"), SelectObj.find('option[selected]'));
        SetResult($("#ResultB"), SelectObj.find('option').filter('[selected]'));
    });
});

测试结果:

+---------------------------+--------------+---------------------+---------+-----+
|          Browser          | Environment  |       jQuery        |    A    |  B  |
+---------------------------+--------------+---------------------+---------+-----+
| Chrome 22.0.1229.94m      | Win7         | 1.8.2, 1.7.2, 1.6.4 | default | new |
| Chrome 23.0.1271.64 m     | Win7         | 1.8.2, 1.7.2, 1.6.4 | default | new |
| Firefox 15.0.1            | Win7         | 1.8.2, 1.7.2, 1.6.4 | default | new |
| Firefox 16.0.2            | Win7         | 1.8.2, 1.7.2, 1.6.4 | default | new |
| IE 6                      | WinXP        | 1.8.2, 1.7.2, 1.6.4 | *new*   | new |
| IE 9                      | Win7         | 1.8.2, 1.7.2, 1.6.4 | default | new |
| Opera 12.02               | Win7         | 1.8.2, 1.7.2, 1.6.4 | default | new |
| Opera 12.10               | Win7         | 1.8.2, 1.7.2, 1.6.4 | default | new |
| Safari 5.1.7 (7534.57.2)  | Win7         | 1.8.2, 1.7.2, 1.6.4 | default | new |
+---------------------------+--------------+---------------------+---------+-----+
| Chrome 22.0.1229.94       | MacOS 10.7.5 | 1.8.2, 1.7.2, 1.6.4 | default | new |
| Chrome 23.0.1271.64       | MacOS 10.7.5 | 1.8.2, 1.7.2, 1.6.4 | default | new |
| Firefox 13.0              | MacOS 10.7.5 | 1.8.2, 1.7.2, 1.6.4 | default | new |
| Firefox 14.0.1            | MacOS 10.7.5 | 1.8.2, 1.7.2, 1.6.4 | default | new |
| Firefox 16.0.2            | MacOS 10.7.5 | 1.8.2, 1.7.2, 1.6.4 | default | new |
| Opera 12.01               | MacOS 10.7.5 | 1.8.2, 1.7.2, 1.6.4 | default | new |
| Opera 12.10               | MacOS 10.7.5 | 1.8.2, 1.7.2, 1.6.4 | default | new |
| Safari 6.0.1 (7536.26.14) | MacOS 10.7.5 | 1.8.2, 1.7.2, 1.6.4 | default | new |
+---------------------------+--------------+---------------------+---------+-----+
| Chrome 21.0.1180.82       | iOS 4.3.5    | 1.8.2, 1.7.2, 1.6.4 | default | new |
| Opera 7.0.5               | iOS 4.3.5    | 1.8.2               | default | new |
| Safari                    | iOS 4.3.5    | 1.8.2, 1.7.2, 1.6.4 | default | new |
+---------------------------+--------------+---------------------+---------+-----+
  • 默认表示它返回选中的{em>默认 option
  • new 表示它返回选中的option

如您所见,除IE6之外的所有浏览器都会产生不同的结果。

5 个答案:

答案 0 :(得分:3)

Sizzle引擎检查元素的selected 属性(包含当前值),而不是属性包含原始(默认)值。

请参阅https://github.com/jquery/sizzle/blob/master/sizzle.js#L788

我还没想到的是为什么你的第二个选择器显然会调用Sizzle,但第一个选择器似乎没有。

无论如何,该属性是您应该检查的属性而不是属性,因此您应该使用:selected伪选择器,而不是[selected]

答案 1 :(得分:1)

当您编写option[selected]时,它将搜索selected属性/属性 而不是你应该使用option:selected 如果您拥有readonly媒体资源且代码为option[readonly],则会返回s

$('[attribute]')将选择具有指定属性的元素,具有任何值 有关更多信息:Has Attribute Selector [name]

<强> Fiddle

<select>
 <option value='p'>p</option> 
 <option value='q' selected>q</option>
 <option value='r'>r</option> 
 <option value='s' readonly>s</option> 
</select>  

答案 2 :(得分:1)

表达式应该返回什么?

[selected]匹配具有selected属性且具有任何值的所有元素(引用:W3CjQuery)。


为什么结果不一致?

我已向jQuery here提交了错误报告。它被标记为another bug report的副本,现已修复


任何解决方案?

获取当前选择

使用:selected选择器(实时演示here):

$('select').find('option').filter(':selected'); /* Supposedly faster */
or
$('select').find('option:selected');            /* Supposedly slower */

请注意,根据doc,第二个表达式应该更慢

  

由于:selected是jQuery扩展而不是CSS规范的一部分,因此使用:selected的查询无法利用本机DOM querySelectorAll()方法提供的性能提升。

获取默认选择

对于 jQuery 1.9 + ,请使用问题中的任何表达式,即

/* A */ $('select').find('option[selected]');
/* B */ $('select').find('option').filter('[selected]');

对于 jQuery 1.6 + ,请使用defaultSelected属性(实时演示here,引用:w3schoolsMozilla,{{ 3}},MSDN):

$('select').find('option').filter(function() {
    return $(this).prop('defaultSelected');
});

答案 3 :(得分:0)

这取决于浏览器如何构造DOM ..使用option[selected] jQuery搜索具有所选属性的选项元素,在某些情况下它不应用

你应该使用

SelectObj.children(':selected')

答案 4 :(得分:0)

你的实施是错误的,不是

find('option[selected]')

应该是,

SelectObj.find('option:selected')

这是编辑过的小提琴:

http://jsfiddle.net/ugXtx/6/

和参考:

http://api.jquery.com/selected-selector/