jQuery - equivalent to each(), but for a single element - javascript

What's the jQuery equivalent for each():
$(".element").each(function(){
// do stuff
});
when attaching a function to a single element, like #element ?

You can always reference the jQuery object in a variable:
var $el = $('#element');
...then manipulate it.
$el.doSomething(); // call some jQuery methods from the cached object
$el.doSomethingElse();
If the reason you wanted .each() was to reference the DOM element as this, you don't really need the this keyword to do it, you can simply grab the DOM element out of the jQuery object.
var element = $('#element')[0]; // both of these give you the DOM element
var element = $('#element').get(0); // at index 0
The two of these are equivalent, and will retrieve the DOM element that would be referenced as this in the .each().
alert( element.tagName ); // alert the tagName property of the DOM element
alert( element.id ); // alert the ID property of the DOM element
I'd note that it isn't necessarily bad to use each to iterate over a single element.
The benefits are that you have easy access to the DOM element, and you can do so in a new scope so you don't clutter the surrounding namespace with variables.
There are other ways to accomplish this as well. Take this example:
(function( $ ) {
// Inside here, "this" will refer to the DOM element,
// and the "$" parameter, will reference the jQuery library.
alert( this.tagName );
// Any variables you create inside will not pollute the surrounding
// namespace.
var someVariable = 'somevalue'; // is local to this function
}).call( $('#element')[0], jQuery );

To directly answer your question, .each() operates normally on element sets of any size including 1.
You can also omit the .each() call completely and just call jQuery methods on $('#element'). Remember that you can chain most if not all jQuery method calls as they return the jQuery object. This even works on multiple elements for the matter, depending on what the methods do.
$('#element').doSomething().doSomethingElse();
If you need to reference the object multiple times, make a variable:
var $elm = $('#element');
$elm.doSomething();
doSomethingElse($elm);

Use first().
each() matches all elements, while first() matches only the first.
There are other selectors too. When you use the id in the selector, you will only get one element. This is the main difference between .element and #element. The first is a class that can be assigned to many elements, while the second is an id that belongs to only (at most) one element.
You can still use each if only one (or 0) element is returned. Also, you can skip each altogether if you want to link an event. You use each when you want to execute a specific function for each element in the list of elements.

If there is only 1 element, you can access it normally using the selector.
$('#your_element').your_event(function() {
});

Behind the scenes, each is just a for loop that iterates through each element in the map returned by jQuery.
It is essentially† the same as:
var i, map = $('...selector...');
for (i = 0; i < map.length; i++)
{
someFunction(i, map[i]);
}
† There's more to it than this, involving calling the function in the context of the map element etc.
It's implementation is to provide a convenient way to call a function on each element in the selection.

Do you mean like $('#element').children().each()
supposing you have something like a ul with an id and you want the li each inside it?

If the intention is to call a (non-jQuery) function in a new scope I think using "each" still is a valid (and probably the most elegant) way and it stays true to the jQuery syntax although I agree to Alex, it feels wrong since it might have some overhead.
If you can change the syntax use $('#element')[0] as replacement for this (as already mentioned in the accepted answer).
Btw could someone with enough reputation please correct the comment of "zzzzBov" about the accepted answer?
$('#element')[0] and $('#element').get(0) ARE! the same, if you want the jQuery object use $('#element').first() or $('#element').eq(0)

Related

What's the difference between an object directly queried and an object querying one of its children?

When I add a class on the following object, everything is fine:
$('.select').on('click', function() {
$(this).addClass('active');
});
But when I try to add a class to a child, I get an error:
$('.select').on('click', function() {
$(this).find('.list')[0].addClass('active');
});
From my research I've learned that certain objects have specific methods that can be called on them. So there must be a difference between
$(this)
and
$(this).find('.list')[0]
But I can't figure out what the difference would be, and I don't know how to find that out.
The difference is that $(this)is a jquery object, while $(this).find('.list')[0] is a DOM element, and doesn't have functions and methodsprovided by jQuery.
Because calling $(this).find('.list') will give you a nodeList and when you call [0] you will get the first node object from this list, and a node or a DOM element is different from a jquery object, as jQuery wraps a DOM elemnt with its utility methods and attributes.
So what you need to do is to convert this DOM element to a jQuery object so you can call jQuery methods on it:
$($(this).find('.list')[0])
$(this).find('.list')[0] returns a dom element from the jQuery object.
Elements don't have an addClass() method and you should be seeing an error in browser console telling you that
If you want the first one you can use first() or eq()
$(this).find('.list').first().addClass('active');
// OR
$(this).find('.list:first').addClass('active');
// OR
$(this).find('.list').eq(0).addClass('active');

JQuery and JavaScript methods

In majority of JavaScript method(iterator) callback first argument is element and second is index. But in case of jQuery always second argument is element and first one is index. Why they formatted differently? Is that for avoiding confusion between them, since both contains methods like map, filter, etc. Is there any special meaning behind that? I'm just curious to know.
This is because jQuery relies on this; it doesn't need an element iterator.
$('selector').each(function(){
// 'this' refers to unwrapped jQuery selector element; no need for arguments == cleaner code
var $this = $(this);
});
In Vanilla JS, iterators rely on the parameters:
[].forEach(function(el, index){
// 'this' refers to Window object; use the argument
el.querySelector('foo')
});
Because jQuery can utilize the scoped element using this, it doesn't really need the arguments. I'd have to look up the history of the library to even see if the element existed as the second argument in earlier versions.

$(".class").width($(this)...) not working

I have a lot of divs with, let's say, the .class class. And I need to assign them a width based on an specific route
$(".class").width($(this).parent().next().find("code").width())
But, for some reason, it doesn't work with $(this) but it does when I do this:
$(".class").width($(".class").parent().next().find("code").width())
but obviously only for the first one. Any clue?
jQuery width() method accepts a function:
A function returning the width to set. Receives the index position of
the element in the set and the old width as arguments. Within the
function, this refers to the current element in the set.
$(".class").width(function () {
return $(this).parent().next().find("code").width()
});
Since classes are meant to be used on multiple elements, your jQuery selector is probably returning a set of elements rather than a single element. Additional jQuery operations such as .width() on a set of matched elements are only executed on the first match. Therefore you'll need to iterate over the matched set of elements in order to complete the function for each match.
$('.class').each(function (idx, elem) {
// Returns the width
// Not sure what the intention is here. Assign to variable maybe?
return $(elem).parent().next().find('code').width();
});
The way you are calling these functions, there is no reason why this should point to each individual .class elements. You are in global context (of whatever), but not in the context of .class DOMElement.
You can use each method instead:
$(".class").each(function() {
$(this).width($(this).parent().next().find("code").width());
});
or width method providing a function as a setter:
$(".class").width(function() {
return $(this).parent().next().find("code").width();
});
Both methods will loop through every element in collection $('.class') and invoke callback functions in the context of every element.

Unwrap safely jQuery instances to get the wrapped DOM element

Wrapping twice an HTML element with jQuery is a safe operation, since it returns an instance of the same DOM element:
var $a = $('#foo');
var $b = $($a);
alert($b.get(0) === $a.get(0)); // true
It allows a flexible setup of configuration objects, which may contain either selectors, or DOM elements, or jQuery instances.
I didn't know it, so in my personal library I extended jQuery with methods to safely wrap and unwrap objects.
Is there in the jQuery core a safe backward operation to unwrap DOM elements from their relative jQuery instances?
I mean something acting like that:
function unwrap(obj) {
return (obj instanceof jQuery) ? obj.get(0) : obj;
}
which is smart enough to allow avoiding that conditional check each time.
Detect DOM object vs. jQuery Object seems to contain the answer to this question.
Each jQuery object has a jquery property. Something like:
function unwrap(obj) {
return (obj.jquery) ? obj.get(0) : obj;
}
It would make more sense to wrap everything in jQuery then just grab the 0th element out of the resulting array:
jQuery( elem )[0];
If passed a jQuery object, jQuery( jQueryObject ) will return the same elements in the same order. If you pass an element this returns the element. If you pass a jQuery object, this will return the first element inside it. If you pass a selector, this returns the first match in the DOM.
We use a similar technique in jQuery UI to basically resolve whatever selector/element/jquery object you passed in the options to a widget.

JavaScript this from jQuery this

Is there a way to get JavaScript this from jQuery this?
this == this, whatever this is.
this is a not jquery it is a special, somewhat convoluted, javascript keyword that describes the current scope of execution.
your challenge may be determining or controlling what this is.
There is:
$('a').click(function(){
var jqueryobject = $(this);
var domelement = this;
});
Within such a closure, this always represent the native DOM element which must/can be wrapped into a jQuery object.
If you already got a jQuery object and need to get the DOM element either use
var DOMelement = $(this)[0];
or
var DOMelement = $(this).get(0);
Since jQuery objects are array like objects you can always grab them with standard array access [] notation. The jQuery method .get() will actually do the same. With both ways, you'll receive the DOM element at that array position.
General - what is this ?
this contains a reference to the object of invocation
this allows a method to know what object it is concerned with
this allows a single function object to service many functions
So this is the most important part of all protoypal inheritance things
I don't really understand what you're asking for here, but I'll give it a shot. Firstly, remember that jQuery is just a series of functions written in Javascript. The this keyword is literally the same in "both" contexts.
Perhaps you want to get the actual DOM element instead of the jQuery object? You can use .get():
// let's say there's a single paragraph element
var obj = $('p'); // obj is a jQuery object
var dom = obj.get(0); // dom is a DOM element
Try to access this (DOM element) instead of $(this) (jquery object).

Categories

Resources