0

Say I have the following elements

<a id="first" class="myLink" data-something="0">First</a>
<a id="second" class="myLink" data-something="0">Second</a>
<a id="third" class="myLink" data-something="0">Third</a>

Then I alter the data-something of the first element like this

$('#first').data('something', 1)

Now, if I do

$('#first').on('click', function(){
    var element = $(this)
    $('.myLink').each(function(){
        if ($(this) == element) {
            alert('equals')
        }
    })
})

an then click the first element, I get no alert.

It seems like the element in $.each() is the one at the load of the document and it doesn't know about the data asignment.

Any clarifications about this? Is there another way of retreiving the current state of elements?

Michael
  • 4,786
  • 11
  • 45
  • 68
  • 1
    Because they are not the same js objects, but the objects with the same data http://stackoverflow.com/questions/1068834/object-comparison-in-javascript As long as every of them has `id` - compare them by id: `this.id == element.id` – zerkms Jun 09 '13 at 05:04
  • 2
    `$()` returns a `new` JS object, and JS objects are never `==` unless they refer to the same object – Ian Jun 09 '13 at 05:05
  • If I set back data to 0, I get the alert – Michael Jun 09 '13 at 05:05
  • If you want to compare these elements, use `var element = this;` and then compare with `if (this === element) {` – Ian Jun 09 '13 at 05:07
  • Yes, I just thought about this, after your first comment. Thank you! I'll try it – Michael Jun 09 '13 at 05:08
  • Here's an example, and shows the index of the specific `.myLink` that matches: http://jsfiddle.net/HEmB7/ – Ian Jun 09 '13 at 05:08
  • 2
    Yes, that's it, Ian. Please write an answer so I can approve it. – Michael Jun 09 '13 at 05:10

1 Answers1

3

The jQuery function ($) returns a new Object (commonly referred to as a "jQuery object"), which represents a collection of DOM elements (as well as some properties and methods to manipulate the collection). Even if the same elements are selected (same or different selectors, even), meaning the jQuery objects contain the same DOM elment(s), they still wouldn't be equal. JS objects are never == (or ===) unless they actually refer to the same object.

For example, $("#element_id") === $("#element_id") is false even though they are selecting the same element.

But var el = $("#element_id"), ref = el; alert(el === ref); would alert true because they both refer to the same object.

If you want to compare these elements, compare references to DOM elements, like this:

$('#first').on('click', function(){
    var element = this;
    $('.myLink').each(function(i, el){
        if (this === element) {
            alert(i + ' equals');
        }
    });
});

DEMO: http://jsfiddle.net/HEmB7/

Something to read about object equality in JavaScript: Object comparison in JavaScript - it is a duplicate, but it, and the duplicated post, contain great information.

Another approach for this comparison is with the jQuery .is() method. If used appropriately, it can be very powerful. It accepts a string selector, function, jQuery object, or DOM element reference. In a simple example like yours, it could easily be used (but I almost find it too much, because a jQuery object needs to be created and extra processing is done by .is()) when you can just use === which is valid and reliable too...although .is() is slightly more readable. Here's how it could be used:

$('#first').on('click', function(){
    var element = $(this);
    $('.myLink').each(function(i, el){
        if (element.is(this)) {
            alert(i + ' equals');
        }
    });
});

DEMO: http://jsfiddle.net/HEmB7/2/

Reference:

Community
  • 1
  • 1
Ian
  • 50,146
  • 13
  • 101
  • 111
  • 3
    `is()` may help here. +1 for explanation. – Jashwant Jun 09 '13 at 05:26
  • @Jashwant Great point, I added something in, thanks for pointing it out. I almost find it a little too much (although you'd never see a real difference in speed or anything), but still a good thing to at least suggest/provide :) – Ian Jun 09 '13 at 05:35