Is there any way to have DOM elements selectable through objects?
For example I want to be able to associate objects to DOM elements like so:
var obj = { a: 1, b:2 };
$('a').click(function() { this.selectThing = obj });
And later on...
$.something(obj);
Or even better:
$('a|selectThing?=', obj);
Something like that. You can see that I want to associate an object to a DOM element in such a way that I can grab the element with the object.
I know this can be done with the filter()
method, my question is if there's a more elegant way that doesn't use filter()
to do this.
EDIT:
To clarify, I want to be able to use an object kind of like a selector, so I can do something similar to this $(obj)
obviously that won't work, but you get the idea (I hope)
EDIT #2:
I want to be able to do something like this:
var obj = { prop: 'prop' };
$('a').bindTo(obj);
$.retreive(obj) // should equal $('a')
I don't want it to alter obj
in any way though (obj
should still be {prop: 'prop'}
only).
JavaScript's Objects are not iterable like arrays or strings, so we can't make use of the filter() method directly on an Object .
The filter() method returns elements that match a certain criteria. This method lets you specify a criteria. Elements that do not match the criteria are removed from the selection, and those that match will be returned. This method is often used to narrow down the search for an element in a group of selected elements.
One can use filter() function in JavaScript to filter the object array based on attributes. The filter() function will return a new array containing all the array elements that pass the given condition. If no elements pass the condition it returns an empty array.
JavaScript objects don't have a filter() method, you must first turn the object into an array to use array's filter() method. You can use the Object. keys() function to convert the object's keys into an array, and accumulate the filtered keys into a new object using the reduce() function as shown below.
var $div1 = $('.box1');
var $div2 = $('.box2');
var obj = { a: $div1, b: $div2 };
obj.a.css({background:'red'});
var obj = { a: $('.box1'), b: $('.box2') };
var obj = $('.box1, .box2'); // store objects
obj.css({background:'red'}); // access collection
You're looking for $.data
. This method associates any JavaScript object or primitive with a DOM element. Under the hood, it's not adding the data as an expando to the DOM element or anything--instead, jQuery maintains its own object cache of DOM elements and data hashes. But that's under the hood; the point is, I think it's exactly what you're looking for.
$('#example').data('foo', { bar: 'quux' }); // returns the jquery object containing '#example', like most jQuery methods
Then, later:
console.log($('#example').data('foo')); // returns {bar: 'quux'}
I dont think this is easily achievable. Let me clarify:
To achieve what you want you would require a hashmap that allows objects in the position of keys. JavaScript does not (yet) support objects as keys in hashmaps though. So, for example, the following does not work:
var key = {value: 'key'};
var data {value: 'data'};
var map = {};
map[key] = data;
There are other solutions to achieve this in current javascript implementations, eg. a double lookup:
var key = {value: 'key'};
var data {value: 'data'};
var map = { keys: [], data: [], get: function (key) {
var k = this.keys.indexOf(key);
if (k >= 0) {
return this.data[k];
} else return undefined;
}, set: function (key, val) {
var k = this.keys.indexOf(key);
if (k < 0) {
k = this.keys.push(k) - 1;
}
this.data[k] = val;
} };
map.set(key, data);
map.get(key).value;
This implementation however is of a terrible performance. There is a proposal for a so called WeakMap in JavaScript Harmony. Firefox I believe is currently the only browser implementing them, though. Since the feature required is not widely available and workarounds are of poor performance I would recommend trying to figure out a different way of achieving what you are trying to.
Extend jQuery with three methods:
jQuery.bindObj(data)
jQuery.unbindObj(data)
$.retrieve(data)
Your code looks like:
$('a').bindObj({blorg: 'shmorg'});
console.log($.retrieve({blorg: 'shmorg'})); // logs live result of $('a');
Full source: http://jsfiddle.net/nUUSV/6/.
The trick to this solution is storing the selectors/identifiers based to the jQuery constructor in one array, and the objects bound to those selectors/identifiers in another array, then using $.inArray
to get the index of the object upon retrieval and using that index to grab the bound jQuery collection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With