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?

7
  • 1
    Because they are not the same js objects, but the objects with the same data stackoverflow.com/questions/1068834/… As long as every of them has id - compare them by id: this.id == element.id Commented Jun 9, 2013 at 5:04
  • 2
    $() returns a new JS object, and JS objects are never == unless they refer to the same object Commented Jun 9, 2013 at 5:05
  • If I set back data to 0, I get the alert Commented Jun 9, 2013 at 5:05
  • If you want to compare these elements, use var element = this; and then compare with if (this === element) { Commented Jun 9, 2013 at 5:07
  • 2
    Yes, that's it, Ian. Please write an answer so I can approve it. Commented Jun 9, 2013 at 5:10

1 Answer 1

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:

Sign up to request clarification or add additional context in comments.

2 Comments

is() may help here. +1 for explanation.
@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 :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.