How to iterate through jQuery elements - javascript

I want to be able to see what's inside the tags that jQuery finds. How come the following doesn't work?
$("div.UIImageBlock_Content.UIImageBlock_ICON_Content").each ( function() {
alert(($this).html);
});
What's the right way to do this?

$this => $(this)
.html => .html()
So this should do it:
$("div.UIImageBlock_Content.UIImageBlock_ICON_Content").each ( function() {
alert($(this).html());
});
Note that html() function just uses the innerHTML property, so it can be a lot simpler:
$("div.UIImageBlock_Content.UIImageBlock_ICON_Content").each ( function() {
alert(this.innerHTML);
});

The current element within a jQuery each iteration can be accessed via this (not $this).
There's a small caveat, however: the this in a jQuery iteration refers to each element's underlying DOM object, not the jQuery object. You can use this code, then:
$("div.UIImageBlock_Content.UIImageBlock_ICON_Content").each ( function() {
alert(this.innerHTML);
});
You don't need to build a jQuery object from the raw DOM object on each iteration — an element's inner HTML is already present in the DOM object, and there's no need for extra work.

Related

Does jQuery re-query the DOM when $(this) is called?

In the following code, when $(this) is called, does jQuery re-query the DOM as though a selector has been passed to it (using some property of the object as a selector), or does jQuery retain the previously returned object?
$('.someButton').on('click', function() {
$(this).remove(); // Is this another lookup, or just a wrapper for the previously returned object?
});
It doesn't re-query the DOM, this is already an element. jQuery simply sets the context to the element, adjusts the length, and returns itself. This code is from the init function, which runs when you do $(something), this is part of a big if..else statement, where it also checks for selectors, arrays among other things:
// HANDLE: $(DOMElement)
} else if (selector.nodeType) {
this.context = this[0] = selector;
this.length = 1;
return this;
So basically it just wraps the element in a new jQuery object.

Determining what the selector is?

I jumped throught the different areas of jQuery source that are called when you type:
$('.foo')
or
$('#foo')
to try and determine how jQuery parses the selector ( I assumed charAt() ) but wanted to verify.
I got to here:
if ( selector.nodeType ) {
this.context = this[0] = selector;
this.length = 1;
return this;
}
But I got kind of stuck on what
selector.nodeType
does. This reference says that a nodeType can be pretty much anything...so what exactly are they checking for?
The jQuery API breaks down the possibilities further.
In summary what is this code snippet trying to accomplish regarding the selector variable?
nodeType suggests that the object passed to the jQuery selector is a DOM node (which will generally be an element). This allows, for instance, the following construction:
$(document)
document is an object that represents the document. $(document) builds a jQuery object based on that element. The test for nodeType means that jQuery can detect whether the argument was an element, and if so simply to build the selection based on that.
You can also see this with the common construction $(this):
$('a').on('click', function() {
console.log($(this).text()); // builds a jQuery selection based on the this
// object, which is the DOM element that was
// clicked
});

why is jQuery selector property undefined within each()?

Given the following code, why does the selector property work in the first instance but not the second? Aren't they both jQuery objects?
<span class='tst'>span</span>​
var tst = $('.tst');
console.log(tst.selector);
// prints '.tst'
$('.tst').each(function() { console.log(this.selector);});
// prints undefined​​​​​​​
this, in the context of the .each() loop, is not a jQuery object, so the selector property is undefined.
You need to make it a jQuery object first: $(this).selector
However, it should be noted that the selector property will return an empty string while inside the .each() loop.
Edit
If you absolutely need the selector property within the .each(), one option would be to cache your selector:
var cached = $('.tst');
cached.each(function() {
console.log(cached.selector); // Will display ".tst"
});
​
this != $(this)
In your first case tst is a reference to the jQuery object, but in the second this is simply the corresponding DOM element.
Within an .each() loop the .selector property is not available, however. To access '.tst' you can do $(this).attr("class") (when you use a class selector) -- though if you already use it in the each you can just cache it in a variable before hand.
Note that this will return all of the classes for that elements, so you can parse it later if it has more than one.
The best workaround based on your exact description is this:
var $tst = $(".tst");
$tst.each(function() {
console.log($tst.selector); //prints .tst
});
However I can't see any reason why you really need to do this.
Working Demo http://jsfiddle.net/wA6Yv/ or http://jsfiddle.net/a3CYR/2/
this != $(this)
If you keen: jQuery: What's the difference between '$(this)' and 'this'?
code
var tst = $('.tst');
console.log(tst.selector);
// prints '.tst'
$('.tst').each(function() {
alert($(this).text());
});
// prints undefined

How to build a cache of the DOM that does not change

So I tried to build a cache of the DOM:
var DOM = document.getElementsByTagName('*');
However, the DOM variable seems to be a dynamic reference, so that if I change an element in the DOM, the DOM variable changes as well.
I tried iterating through the DOM variable and using the cloneNode method to create a deep copy of each node. This works in that it does not change when I change the DOM. However, the problem is that a cloned node does not equal its original DOM node when you compare them with the === operator.
So to sum up, I'm looking to create a cache of the DOM that does not change but whose nodes are still equal to the original DOM nodes.
document.getElementsByTagName returns a "live" NodeList, which isn't what you think at all. When you access the list, the DOM is traversed (implementation may cache it) every time to get the result. This gives the illusion of the list being live.
document.getElementsByTagName("div") === document.getElementsByTagName("div")
//true
To do what you want, simply convert it to an array. DOM = [].slice.call(DOM)
You seem open to a jQuery solution, so:
$("*")
will return a jQuery object containing all the elements. It will not be updated as the DOM changes.
Or if you just want elements within the <body> (i.e., not <script> or <meta> elements, etc., from the <head>) then:
$("body *")
Being a jQuery object it will of course allow you to access jQuery methods, but you can also access the DOM elements directly with array notation:
var DOM = $("body *");
DOM.show(); // example jQuery method call
alert(DOM.length); // show count of elements in DOM
alert(DOM[4].value) // example of direct access to fifth DOM element
I prefer to use the following methodology:
https://gist.github.com/3841424#file-domcache-js
Or, you may replace the DOM object with a method in this implementation:
var myNS = {
myEventHandler: function(event){
this.DOM.$el.doSomething();
},
cacheDOM: function(){
return {
$el: $("#matrix")
};
},
initialize: function(){
this.DOM = this.cacheDOM();
}
};

value in .each() loop

when i use jQuery .each() function, it is give me index and value of current element.
I have a this code
$('.scrollbar').each(function (index, value) {
//some code
});
the value is an DOM or jQuery object
It's the underlying DOM object. It's easy to be proven:
$('.scrollbar').each(function(index, value) {
alert(value.jquery);
});
shows undefined.
Whereas:
$('.scrollbar').each(function(index, value) {
alert($(value).jquery);
});
shows the version of jQuery which is attached to all jQuery objects.
You can also use this:
$('.scrollbar').each(function (index, value) {
var DOM = this,
jq = $(this);
});
The value refers to the same object as the this object, so it will be the DOM object.
It is a DOM object. To get the jQuery object you can use $(value).
It refers to the current DOM element that your Jquery function is reffering to...
In this case your DOM element which has a class of .scrollbar is currently referred to...
As niels says, use "this" pointer to access the current DOM element.
Hope this helps :)

Categories