9

设想:

我有 2 个 jQuery 表达式:

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

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

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

预期行为:

AB应该给出相同的结果。

实际行为:

用户更改下拉菜单中的选择后,

  • A返回默认的selected 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/> 

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 |
+---------------------------+--------------+---------------------+---------+-----+
  • default表示它返回默认的selected option
  • new意味着它返回的selected option

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

4

5 回答 5

3

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

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

我还没有弄清楚为什么你的第二个选择器显然调用了 Sizzle,但第一个似乎没有。

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

于 2012-10-30T11:37:25.807 回答
1

when you write option[selected] it will search for the selected attribute/property instead of that you should use option:selected if you have readonly property and you code option[readonly] it will return s

$('[attribute]') will selects elements that have the specified attribute, with any value.
for more information : 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>  
于 2012-10-30T11:20:43.567 回答
1

表达式应该返回什么?

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


为什么结果不一致?

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


有什么解决办法吗?

要获取当前选择

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

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

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

因为:selected是 jQuery 扩展而不是 CSS 规范的一部分,所以使用的查询:selected不能利用原生 DOMquerySelectorAll()方法提供的性能提升。

要获得默认选择

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

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

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

$('select').find('option').filter(function() {
    return $(this).prop('defaultSelected');
});
于 2012-11-07T02:39:59.317 回答
0

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

你应该使用

SelectObj.children(':selected')
于 2012-10-30T11:19:31.850 回答
0

你的实现是错误的

find('option[selected]')

它应该是,

SelectObj.find('option:selected')

这是编辑过的小提琴:

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

和参考:

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

于 2012-10-30T11:22:33.913 回答