jQuery $('element', this) selector, what does it mean? - javascript

I used this selector in a function and I don't even know exactly what it means, but it worked - here is my piece of code:
else if($(this).hasClass('list')) {
listItem.stop(true,true).fadeOut(333, function(){
var $this = $(this);
if(listItem.hasClass('grid')) {
$this.find('h1', this).insertBefore($this.children());
}

The ".find()" method only pays attention to one argument, so it means exactly the same thing as
$this.find('h1')
JavaScript doesn't care if you pass too many arguments to a function; in fact there's no such concept as "too many arguments".

You can use a context in the $() function, like this:
$('element', this)
It will then only search among the decendants of the element that this referens to.
It's equivalent to using the find method:
$(this).find('element')
Using find with two parameters is pointless, though. It will only ignore the second parameter.

It is an alternative selector context to be used instead of the document root for the jQuery constructor.
The .find() method will ignore any other arguments than the selector. Its search context node is given as the context of the function call.

Related

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.

Automatically return jQuery object

In jQuery, when I call:
$("selector").a_function(function(){
this.toggleClass("a-class");
}
I am told that this is of a certain type, and does not have the jQuery function available to it. The problem is that I am not getting jQuery objects returned to me. The way I am getting around this is to do:
jquery_object = jQuery(this);
every time. I thought that $() is equivalent to calling jQuery and that I am supposed to receive a jQuery object.
Is this normal? What am I doing wrong here?
You'll want to use $(this) instead of just this.
In the case you gave this doesn't refer to the DOM element.
By wrapping it in the standard JQuery selector function, you'll actually be calling to the DOM element.
I use this a lot for click handlers.
$('a').click(function(e) {
$(this).toggleClass('a-class');
});
Pretty much any function in JQuery that gets called through a selector and has a callback will use this format.

What's the name of jQuery functions that don't accept functions as parameters

This a theoretical question:
Is there a generic name to refer to all those jQuery functions that don't accept functions as a parameter?
Such the index(), children(), height() ...
UPDATE:
If i know the name then I could make a question like this: "Can I pass a function to a "named" function?"
To give a little more detail, I have tried to pass a function as a parameter to jQuery's .index() method but it does not work:
textbox.closest('tr').index(function(){var index = $(this);});
All jQuery functions that take parameters can take functions. In JavaScript, functions are objects, and neither jQuery or vanilla JavaScript are type-safe. In other words, as long as the function accepts parameters, it will accept a function as one of its arguments.
Ergo, methods that do not accept any parameters are the only methods that will not accept functions.
EDIT:
If you want to get technical, then even methods that do not accept any parameters will still accept a function as an argument. Just as JavaScript isn't type-safe, it also doesn't actually enforce any rules regarding the function's signature, i.e. it doesn't check that the number of arguments entered matches the number of arguments defined. This is why you get a "null reference" error (if unhandled) instead of a "no function [function name] takes the arguments [arguments list]". This is also why you can pass an unlimited number of arguments to a function, even if it only takes one, two, or none.
UPDATE:
With regards to my solution to your original question, I would like to clarify by adding that jQuery is a solid language in that it often will simply return null when it is passed invalid arguments (but it will not error out when being passed an incorrect number of arguments). JavaScript is the same in many situations, but, as I implied and common sense would dictate, it would be nonsensical to pass too many or too few arguments to a method, regardless of legality.
With regards to your updates and your comments, I think that you're misunderstanding the fundamental use of jQuery's .index() method. When used properly, this method is called on a collection of elements and has a selector (or an element to match) as a parameter, and returns the index of the first occurrence of an element that satisfies the given selector, or matches the given element.
Update:
From your updated example, I can see that I was correct in thinking that you are misunderstanding the use of the .index() function a little bit. The function takes either a selector or an element, but you passed a function that doesn't return either. Here is what you would need (using your existing syntax):
textbox.closest('tr').index(function(){ return $(this);});
OR (more simply):
textbox.closest('tr').index($(this));
To add a bit more detail (and, perhaps, better answer your initial question), you could also do something like this:
function getOnlyParagraphElements() {
return this.tagName === "p";
}
var collection = $("body").find("*");
var firstParaIndex = collection.index(getOnlyParagraphElements);
This was only an example (and yes, I know that I could just use jQuery to get paragraphs), but the concept is the same - this is how you make your own selector.
Also note that in your examples, you are always checking against a one-item collection, meaning you will only get either the value 0 or the value -1 (if the element doesn't match the selector/passed in element). If your goal is to get the index of the element that you are calling the method on relative to its siblings, then you need only call the method without supplying any parameters.

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

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)

Understanding javascript function calls in format of myFunc(arg).something()

I'm trying to understand the format of the Javascript functions that jQuery, among other people, use.
For instance jQuery(arg).hide() or $("#obj").hide
I'd like to write similar format functions but I don't understand how.
I know how to write
function myFunc(args) {
}
but I don't understand the second part ie the .hide()
is that a function within a function?
thanks for any help
It's called method chaining. The way to achieve this is for your first function to return an object, so the second function can be called as a method on that object.
The standard way to do this style of programming is to always return the same type of object, so for example, jQuery always returns a jQuery object representing a collection of HTML nodes. If one of the calls modifies the collection then the next call will be on that collection. That's how you can do something like $('#myid').parent().hide();. $('#myid') returns a jQuery object representing the #myid element and .parent() returns a jQuery object representing the parent element of #myid. .hide() returns the same object, so you could then call another method on the same object if you wanted.
This is called method chaining. I highly recommend picking up Crockford's "JavaScript: The Good Parts". This is a very quick read but wonderfully explains OOP in JavaScript and identifies good versus bad language features. Highly recommend it.
As Skilldrick pointed out, this is called method chaining.
The most straightforward example for this is an object that returns itself when you call any of its methods:
var world = {
'hello': function() {
alert('Hello');
return this;
},
'goodbye': function() {
alert('Goodbye');
return this;
}
};
world.hello().goodbye();
This is identical to world.hello(); world.goodbye();.
jQuery does a little more than that. Calling the jQuery or $ function on a valid selector string will return a jQuery object representing the matched elements (it's not actually an array, though you could think of it as one). Most of its methods will return the object itself after modifying the object (e.g. $("a").css({...}) will apply changes to the styling of the matched elements and then return the set of matched elements again).
But some jQuery methods allow modifying the set you're working with (e.g. $("a").parent() will return a jQuery object representing the parents of the matched elements). That is, they don't return the same object, but an object that behaves identically.
You have to be careful if you decide to use this style, though, as the flow will break if you need a method that has a return value of its own (e.g. if you want calculations or getter methods). This can be avoided by passing a callback function to the method, but the resulting coding style may be terribly convoluted.

Categories

Resources