Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between find('option[selected]') and find('option').filter('[selected]')

Scenario:

I got 2 jQuery expressions:

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

which mean (let's assume there's only one select in the document, for simplicity):

  • A: Get the select, then find all option descendants that has an attribute named selected.
  • B: Get the select, then find all option descendants, then filter by those who has an attribute named selected.

Expected Behaviour:

A and B should give the same result.

Actual Behaviour:

After the user changed the selection in the dropdown,

  • A returns the default selected option.
  • B returns the new selected option.

Question:

So why are they different? Is my understanding about CSS selectors wrong?

Live Demo:

Live demo is here here.

Source Code:

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]'));
    });
});

Test Result:

+---------------------------+--------------+---------------------+---------+-----+
|          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 means it returns the default selected option.
  • new means it returns the new selected option.

As you can see, all browsers except IE6 give different results.

like image 959
Pang Avatar asked Oct 30 '12 11:10

Pang


1 Answers

The Sizzle engine checks the selected property of an element (which contains the current value) rather than the attribute which contains the original (default) value.

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

What I haven't figured out yet is why your second selector apparently invokes Sizzle, but the first one doesn't seem to.

In any event, the property is what you should be checking rather than the attribute, so you should be using the :selected pseudo-selector, and not [selected]

like image 156
Alnitak Avatar answered Oct 02 '22 22:10

Alnitak