2

I just want to share an experience with you all. So my problem was, that I came across the problem of binding javascript back-end objects to HTML front-end elements. Now, i have searched through google and read some stackoverflow articles about this problem, and many posts answer to this is to use jQuery.data(), however in my first attempts I did not succeed because there was something I did not know about jQuery's object creation method. My problem was that, I wanted to retrieve the stored data outside of the scope where i stored this, and jQuery always(i think) returns a new object reference when i write jQuery('selectorID'). So for example:

var ref1 = $('#myID');
var ref2 = $('#myID');

if(ref1 == ref2)
{
   alert(true);
}
else
{
   alert(false);
}

Will always alert false. However replacing the jQuery method with javascript's built-in getElementById() we will get the same reference! Hence the following code will always alert true!

var ref1 = document.getElementById("myID");
var ref2 = document.getElementById("myID");

if(ref1 == ref2)
{
   alert(true);
}
else
{
   alert(false);
}

The little morale of my story is that if you want to globally bind javascript objects to HTML elements and are thinking about using jQuery's data() method, store the data on the reference returned by javascript's built-in getElementById(). That way, whereever you retrieve the reference with getElementByID, you will always get the same reference and can get the data from it using jQuery's data() method.

My Questions:

  1. Is my logic of thinking ok?
  2. Is there a better way to globally bind javascript objects to HTML elements?
1
  • 1
    Your logic is patently false. While multiple calls to $() return different selector objects, jQuery methods usually operate on the selected objects themselves. Calls to .data() will thus always operate on the same DOM element you'd get using getElementById(). (As you could've determined by actually trying this out instead of investigating reference equality.) Commented Mar 10, 2013 at 13:22

4 Answers 4

2

Whatever the reason behind the code you mention not working was, it was decidedly not the fact that jQuery gives you a new collection for every query. Given the HTML:

<div id="somediv"> foo bar </div>

the following Javascript works as expected:

var $ref1 = $('#somediv');
var $ref2 = $('#somediv');

console.log("$ref1:", $ref1);
console.log("$ref2:", $ref2);

// compare the collections / references
console.log("$ref1 == $ref2:", $ref1 == $ref2); // => false
console.log("$ref1 === $ref2", $ref1 === $ref2); // => false

// compare the referred DOM elements themselves
console.log("$ref1[0] == $ref2[0]:", $ref1[0] == $ref2[0]); // => true
console.log("$ref1[0] === $ref2[0]", $ref1[0] === $ref2[0]); // => true


$ref1.data('somedata', 'SOMEDATA');
console.log('$ref1->somedata:', $ref1.data('somedata')); // => SOMEDATA
console.log('$ref2->somedata:', $ref2.data('somedata')); // => SOMEDATA
Sign up to request clarification or add additional context in comments.

7 Comments

I never said that jQuery returns a new collection for the same query, what I said was that jQuery return a new REFERENCE to the same objects(from the perspective of content) returned!
Also, what I wanted to do is to store some data on the references to those DOM elements
@Fazi Your question says "binding javascript back-end objects to HTML front-end elements". .data() will bind arbitrary objects to the DOM elements. When I said that jQuery (i.e. the function $()) returns collections of DOM elements, it's because that's what it does. ref1 and ref1 in your code are "smart" arrays of DOM elements, not references. In jQuery, you can usually treat such an array that only has one item as a reference to said item, but it's still an array.
@Fazi Now, if you want to bind objects to said array/reference, just use your own custom properties, although it'd be best to namespace them somehow to avoid clobbering jQuery methods. If you want to bind to the DOM elements, use .data(), which will in fact bind to the DOM elements themselves, not to the references, as my code sample shows. If you want to do something else entirely, maybe you should post a question asking how to do that - you've never actually provided any example of what you're trying to accomplish.
From my understanding, and related to this post(stackoverflow.com/questions/3691125/objects-in-javascript), all variables in Javascript are stored in a heap. So basically a query with jQuery(even if it seemingly returns the same object) returns a reference to a totally new object. So for example, ref1 and ref2 in my code are references to different "smart" arrays. Although, you are right in the sense that this was, truly beside the point of my my post.
|
0

The way I do it is something like this.

var ref1 = $('a');
var ref2 = $('div');

var equal = ref1.length === ref2.length;
if (equal) {
    $.each(ref1, function(i) {
        equal = equal && ref1[i] === ref2[i];

        if (!equal) {
            return false;
        }
    });
}

if (equal) {
    alert(true);
} else {
    alert(false);
}

1 Comment

I don't believe "how to compare jQuery objects for identity" is the OP's question, just an observation he made.
0
ref1[0] === ref2[0] // Should return true

I think jQuery's instances are unique, so you can compare its matched items, which should be just one element when you reference an ID.

You could do something like this:

var ref1 = $('#myID')[0];
var ref2 = $('#myID')[0];

1 Comment

As I commented elsewhere, "how to compare jQuery objects for identity" doesn't seem to be the thrust of the OP's question
-1

I dive into jQuery's source code, and find the constructor of jQuery. As follow:

// Define a local copy of jQuery
jQuery = function( selector, context ) {
    // The jQuery object is actually just the init constructor 'enhanced'
    return new jQuery.fn.init( selector, context, rootjQuery );
}

Whenever you use ref2 = $('#myID') to retrive a corresponding jQuery element, jQuery will create a new object to you. So the == will return false to you coz' the two element is completely different to js object engine.

Seems getElementById method is more fit your need. But I don't know how js engine perform its getElementById method.

1 Comment

Unless the OP needs to compare elements for identity, there's no reason to not use jQuery.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.