joews
joews

Reputation: 30330

Find data() key-value pairs for every element

What is the best way to view all jQuery data key-value pairs across every element (in jQuery 2.x)?

A selection-oriented approach ( e.g. $('*').data() ) obviously does not work, because the return value is tied to a single element.

I know that I can iterate over every element, checking each for data:

var allData = [];
$('html *').each(function() {
    if($.hasData(this)) {
        allData.push({ el: this, data: $(this).data() })
    }
})

JSFiddle

This does produce the expected output, but iterating over each possible data key feels like a backwards approach to this problem.

Is there some way to find all element data directly?

N.B. I'm interested for debugging, not production code.

Upvotes: 0

Views: 1265

Answers (1)

SVSchmidt
SVSchmidt

Reputation: 6567

You could select every element within the body with $("body *") and apply jQuery's .filter() to it. Working example:

var $elementsContainingData $("body *").filter(function() {
    if($.hasData(this)) return this;  
});
console.log($elementsContainingData);

Edit

As @spokey mentioned before, there's an internal variable named "cache" within the jQuery object: $.cache.

This variable consists of a bunch of objects which contain keys like "data" or "events":

5: Object
data: Object
events: Object
handle: function (a){return typeof m===K||a&&m.event.triggered===a.type?void     0:m.event.dispatch.apply(k.elem,arguments)}
__proto__: Object

You can iterate through that object and filter for the data:

var filteredCache = $.each($.cache,function() {
        if(typeof this["data"] === "object") return this;
    });

Here's an working example plus a function to merge that stuff into a single and more handy object consisting only of dataKey => dataValue pairings: Fiddle

Edit

As mentioned in comments this solution does not work in jQuery version 2.x since $.cache is deprecated.

My last suggestion is creating a hook for jQuerys data function in order to extend an own object$.dataCache = {}; each time data() is called. Extending, replacing or adding jQuerys functions is done by accessing $.fn.functionName:

$.fn.data = function(fn,hook) {
    return function() {
        hook.apply(this,arguments);
        return fn.apply(this,arguments);
    }
}($.fn.data,function(key,value) {
    var objReturn = {};
    objReturn[key] = value;
    $.extend($.dataCache,objReturn);
});

This also works great in jQuery version 2: Fiddle

Upvotes: 1

Related Questions