Using javascript "this" for jquery selector - javascript

In this code, we can obtain value of element id as 2 differnt way and both way return resultat
$("#my_div").on("click", function () {
alert( $(this).attr("id") );
alert( this.id );
});
But i interest, second way, is it proper in this case? I ask this, because in code we use jquery selector and for jquery selector, write clear javascript: this is justified and will it work always? or may be better use jquery $(this) for jquery selector? or not differnce?

this.id will give you the internal DOM element property while $(this).attr("id") returns the value of 'id' attribute.
The alternative to this.id in jQuery is using prop() method: $(this).prop("id"). However, using pure this.id construction will be easier and faster.

The main jQuery constructor can take a number of different types of argument.
In that context, this is not a selector, it is an HTMLElementNode (which jQuery calls an element).
This is perfectly OK and documented.
There is no need to spend the resources in wrapping an element in a jQuery object if you are just going to grab its ID. There aren't any compatibility problems between browsers for that.
Grabbing the id property of an HTMLElementNode takes less code and is faster then wrapping the whole thing in jQuery.

Yes, your second way is proper.
$("#my_div").on("click", function () {
// this is available within this function
alert( this.id );
});
this refers to an HTMLDOMElement within the function, and wrapping that this within $() will give you an jQuery object.
If you define another function within the click handler. Ex:
$("#my_div").on("click", function () {
// keep reference of this
var that = this;
function test() {
// this will not available here directly
// instead of that you can use reference
alert(that.id);
}
});
And $(this).attr('id'), this.id or $(this).prop('id') will give you the same result.

For choosing the best method is not always clear.
In this case you want the this.id, because the other solution requires much more calls behind the scenes (obvious calls to jQuery and attr).
If you need more information that mite differ from browser, you want the jQuery way.

Related

jQuery / JavaScript, why do I need to wrap variables in $() to use them?

Say I have a map on an array of elements. The callback function takes the index and the value at that position in the array.
If I wrap the array element that the callback receives in $(), it behaves as I expect. If I use it without wrapping it in $(), it gives an error.
var nonHiddenElements = $( "form :input" ).not(':hidden');
nonHiddenElements.map(function(index, element){
input_id = $(element).attr('id'); // this works
input_id = element.attr('id') ; // this gives an error
})
Can someone explain how this works.
Is this a jQuery quirk, or a JavScript thing?
What type of objects does my nonHiddenElements array contain exactly?
What is element that gets passed to the callback?
And mainly what is the $() doing?
You need to understand how jQuery actually works. I will try to explain it briefly.
$ is nothing but a normal javascript function. jQuery === $, is just a function with a fancy name. This function does a lot of different things, depending on what you pass in it. For example if you pass a string it will be treated as CSS selector and jQuery internals will try to find corresponding DOM elements. Or if you pass a string starting with < and ending with > jQuery will create a new DOM element by provided HTML string.
Now if you pass a DOM element or NodeCollection of DOM elements, it/they will be wrapped into jQuery instances so that they can have a jQuery prototype methods. There are many prototype methods jQuery offers. For example text, css, append, attr - those are all methods of jQuery prototype. They are defined basically like this (simplified):
jQuery.prototype.text = function() { ... }
Normal DOM elements don't have those convenient methods jQuery provides. And inside of methods like map or each if you check this value or element parameter like you do, you will see that they are actually not jQuery instances:
element instanceof jQuery // => false
and of course you can't use instance methods with not an instance.
So in order to use jQuery prototype methods you need have a jQuery instance, which you can obtain if you call jQuery function with DOM element passed in it:
$(element) instanceof jQuery // true
Javascript is a programming language.
jQuery is a JavaScript Library.
With jQuery:
$("some element")
In native JavaScript you would have to do something like this.
getElementById('elementByID')
Explained in detail here: https://developer.mozilla.org/en-US/docs/Web/API/document.getElementById
MDN is a great resource for beginners. https://developer.mozilla.org/en-US/docs/Web/JavaScript

Using this this in Jquery

I am having trouble with this in Jquery. When I do that on my website, it returns me the window.width. I just want to access the element from within. This is an example.
<div class="section " style="width:400px"></div>
$( ".section" ).html($(this).width());
or
<div class="section "><p></p></div>
$( ".section p" ).html($(this).parent().width());
also here is JSFiddle jsfiddle.net/XY66w/1
I'm going to assume that when you attempt to write this code:
<div class="section " style="width:400px"></div>
$( ".section" ).html($(this).width());
What you're trying to do is show 400px inside the div.section. If that is what you're trying to do, then here's what's happening:
This statement:
$( ".section" ).html($(this).width());
if Javascript, or most other languages I know, is syntactically equivalent to this:
var newHTML = $(this).width();
$( ".section" ).html(newHTML);
As you can see, this isn't a jQuery issue - but more a JavaSciprt / any programming language problem. You're telling the browser to pass in a value to the .html() method, so it must calculate that value first, in the scope of the function that you're calling the method from. In this case, you're calling the method from the window or global scope (or some other undefined scope, so you will never get what you expect.
The simple fix is this:
var section = $('.section');
section.html(section.width());
On the other hand, there are some jQuery methods that accept functions and these are the ones that you seem to be thinking of in this case. For instance, things would be slightly different in case you were using the each method, which accepts a function:
$('.section').each(function(index, element){
$(this).html($(this).width());
});
In this case, you're passing in a function that jQuery will then call in the scope of each element that is matched by your selector.
The big difference is to differentiate when you're passing in a value and when you're passing in a function that will be evaluated later.
You can do what you want this way, I think:
$(".section").each(function() {
$(this).html($(this).width());
});
JavaScript, like a lot of common languages, is not a "lazy" language. An expression statement like yours is evaluated such that all the function parameters are determined before anything's actually called. By using the jQuery .each() API, you can act on each element of the selected set.
jQuery only binds this when it's calling a function, such as an event handler, a callback function, a function supplied to something like $.each, etc.
In your examples, you're just supplying an argument to a jQuery method, and it's not inside a function that was called by jQuery. So this just contains whatever the browser's context is, which is window for top-level code. It's not the element(s) matched by the selector .section.

jQuery get searched selector, if element doesn't exist

If an element doesn't exist, how do I get a string of the selector that was searched?
For example:
$( 'parent child.class' ).plugin( )
In my plugin, I want to get the string "parent child.class", but $( 'parent child.class' ) doesn't exist.
I'm going to start digging through the jQuery source code, but I figured I'd ask in case someone with more intimate knowledge knows this.
You can't.
jQuery objects have a .selector property, which you could use within your plugin (though it seems to be intended for use interally with jQuery), but - and it's a big but - not all jQuery objects are created with a selector string. Consider this example use of .yourPlugin():
$('div.someClass').add(document.getElementById("test"))
.add("<div>Hello</div>")
.filter(function() {
return $(this).attr("data-test") == "blah";
})
.parents()
.yourPlugin();
It doesn't make sense to be thinking about what selector resulted in the jQuery object eventually passed to .yourPlugin(), regardless of whether it contains any elements.
(I suppose if you know your plugin will only ever be used by you and you'll only ever pass it jQuery objects created with a selector then you could use this.selector within your plugin...)
there is selector property:
$.fn.plugin = function() {
if (this.length == 0) {
return this.selector;
}
};

Most efficient way to re-use jQuery-selected elements

I can imagine the correct answer to this based on theory, but I'm just looking for some confirmation. I'm wondering what the most efficient way to re-use a jQuery-selected element is. For example:
$('#my_div').css('background','red');
//some other code
$('#my_div').attr('name','Red Div');
vs.
myDiv = $('#my_div');
myDiv.css('background','red');
//some other code
myDiv.attr('name','Red Div');
I assume the second example is more efficient because the element #my_div doesn't have to get found more than once. Is that correct?
Similarly, is it more efficient to first save $(this) in a varaible, such as 'obj', and then reuse 'obj' rather than using $(this) over and over? In this case, jQuery isn't being forced to find an element over and over again, but it IS being forced to convert this to a jQuery object [$(this)]. So as a general rule of thumb, should a jQuery object ALWAYS be stored in a variable if it will be used more than once?
You should write your code such that you limit the number of DOM traversals.
When you write something like this:
$('#my_div').css('background','red');
//some other code
$('#my_div').attr('name','Red Div');
You are finding #my_div twice, which is inefficient.
You can improve this either by assigning the result of a selector (i.e. var x = $('.something')) and manipulate the variable x, or you can chain your method calls like this:
$('#my_div').css('background','red').attr('name','Red Div');
You'll see the above code used a lot, because you're finding the element once. The css() method will apply a CSS style and return the actual result of $('#my_div'), so you can invoke another method, in this case attr().
My preferred way of handling the re-use of selectors is to store them as a variable, and wrap my stuff in a closure.
if you're using jQuery selector (like $('#element')), then yes, you should always store your results.
if you're using object and wrapping it in jQuery (like $(this)), it's not necessary, because jQuery doesn't need to search for that element again.
One thing that I find is generally overlooked is just how powerful jQuery chains are. It may not be so noticeable, but since jQuery caches your wrapped elements within a chain, you can modify elements, go into a more specific subset, modify, then go back up into a a general superset without much overhead.
I expect something like (pardon the example)
$('#myDiv')
.addClass('processing')
.find('#myInput')
.hide('slow')
.end()
.removeClass('processing')
;
to be better performance-wise than even
var $myDiv = $('#myDiv').addClass('processing');
var $myInput = $('#myDiv #myInput').hide('slow');
$myDiv.removeClass('processing');
This also holds for applying the jQuery function to elements returned in an event handler. Try to avoid applying $(...) too many times, because this is slow. Instead create a variable that contains the result of $(...). Good practice is to start the variable with a $, which gives a hint about the jQuery object inside the variable.
$('a').click(function(){
var $this = $(this);
$this.addClass("clicked");
$this.attr("clicked", true);
});

Why do I have to use $(this)? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
jQuery $(this) vs this
In jquery sometimes I find that within a function I have to use $(this) because this won't work:
var listItems = $('li');
listItems.each(function(index) {
$(this).css({
})
})
Any ideas as to the reason why?
$() is the jQuery constructor function
this is a reference to the DOM element of invocation
So basically, you're turning a DOM reference into a jQuery object
In your example, you could also use
listItems.each(function(index, element){
$(element).css({
});
});
..since .each() will pass both, index + element in its callback.
I know I'm a bit late to this thread but I just wanted to bring up the fact that redundant wrapping of DOM objects is one of the most frequently committed crimes against jQuery. Taking care with your jQuery-instance constructing can have tremendous effects performance-wise and it's so easy to do that you have no excuse not to.
Typically, when people have a DOM object (whether it be referenced as this or element) they'll try to wrap it each time they need access to a jQuery method:
jQuery(this).css('a', 'b');
The problem is when you're doing this multiple times:
jQuery(this).css('a', 'b');
jQuery(this).find('span').attr(...);
jQuery(this)....
Every time jQuery() is called, a new jQuery instance is constructed. That kind of operation is expensive and should be avoided if at all possible -- especially in loops!
To avoid this, for one, you could utilise chaining with all methods that return a jQuery instance $(this).css(a,b).attr(a,b)...). The rest of the time you should have a locally declared variable that refers to the jQuery instance and then just use that:
var self = jQuery(this);
self.css(...);
self.attr(...);
If you're doing this within an .each() callback function, there is still a new jQuery object being constructed on every single iteration. You can avoid this by having one generic jQuery object which you continually mutate and then you can run jQuery methods off that single instance:
Look at this:
jQuery.single = function(a){
return function(b){
a[0] = b;
return a
}
}(jQuery([1]));
Now look at this:
$('a').each(function(i){
$.single(this).append('Anchor number ' + i);
});
Only one jQuery object is being used. You can make it even faster by avoiding the identifier resolution:
$_ = $.single;
$('a').each(function(i){
$_(this).append('Anchor number ' + i);
});
Food for thought. More info here: http://james.padolsey.com/javascript/76-bytes-for-faster-jquery/
this is the native DOM element. $(this) is a jQuery object that allows you to call functions such as .css() on it.
this is typically a DOM object by default, which means it only has the methods on normal DOM objects.
If you want to invoke a library-specific function (such as jQuery's .css function), you have to convert it to a full jQuery object first, which is what $() does by default if you pass it a DOM object.
(You can also pass other things to $(), such as an HTML string (to construct a new jQuery-wrapped DOM object) or a CSS selector (to get a set of jQuery objects that correspond to DOM objects matching the selector).
If you are using Firefox, try console.log($(this)) and console.log(this) to see the difference.

Categories