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

Pan*_*ang 9 jquery html-select jquery-selectors

场景:

我有2个jQuery表达式:

/* A */ $('select').find('option[selected]');
/* B */ $('select').find('option').filter('[selected]');
Run Code Online (Sandbox Code Playgroud)

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

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

预期行为:

AB应该给出相同的结果.

实际行为:

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

  • A返回所选的默认值option.
  • B返回选中的option.

题:

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

现场演示:

现场演示 这里.

源代码:

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/> 
Run Code Online (Sandbox Code Playgroud)

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]'));
    });
});
Run Code Online (Sandbox Code Playgroud)

测试结果:

+---------------------------+--------------+---------------------+---------+-----+
|          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 |
+---------------------------+--------------+---------------------+---------+-----+
Run Code Online (Sandbox Code Playgroud)
  • default表示返回默认选择option.
  • new表示它返回选中的option.

如您所见,除IE6之外的所有浏览器都会给出不同的结果.

Pan*_*ang 1

表达式应该返回什么?

[selected]匹配具有selected任意值的属性的所有元素(参考文献:W3CjQuery)。


为什么结果不一致?

我已在这里向 jQuery 提交了错误报告。它被标记为另一个错误报告的重复,该报告现已修复


有什么解决办法吗?

要获取当前选择

使用选择器(此处:selected为现场演示):

$('select').find('option').filter(':selected'); /* Supposedly faster */
or
$('select').find('option:selected');            /* Supposedly slower */
Run Code Online (Sandbox Code Playgroud)

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

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

要获得默认选择

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

/* A */ $('select').find('option[selected]');
/* B */ $('select').find('option').filter('[selected]');
Run Code Online (Sandbox Code Playgroud)

对于jQuery 1.6+,请使用该属性(此处defaultSelected为现场演示,参考文献:w3schoolsMozillaMSDNMSDN):

$('select').find('option').filter(function() {
    return $(this).prop('defaultSelected');
});
Run Code Online (Sandbox Code Playgroud)