How is "this" used in this JS code [duplicate] - javascript

This question already has answers here:
What's the difference between '$(this)' and 'this'?
(7 answers)
Closed 8 years ago.
I've been reading quite a bit now, but I still haven't gotten a explanation that would make sense, from a noobs perspective.
$(document).ready(function() {
$("#slideshow").css("overflow", "hidden"); /*kuna JS t66tab siis ei ole vaja scrollbari n2ha*/
$("#slideshow-nav").css("visibility", "visible"); /*nupud tehakse n2htavaks*/
$("#slideshow-nav a[href=#pilt1]").addClass("active"); /*muudetakse esimene nupp aktiivseks*/
$("#slideshow-nav").localScroll({ /*see funktsionaalsus pärineb ka http://flesler.blogspot.com/*/
target:'#slideshow', axis: 'x' /*vajalik scrollTo ja localscroll kasutamiseks, paneb paika,et need pluginad liigutaksid slaidi pilte mööda x-telge*/
});
$("#slideshow-nav a").click(function(){
$("#slideshow-nav a").removeClass("active");
$(this).addClass("active"); /*kui vajutada uuele nupule v6etakse aktiivne klass sealt 2ra ja lisatakse vajutatud nupule*/
});
});
What purpose does $(this) have in context to this: $(this).addClass("active");, I understand what the code itself does, but what is the purpose for $(this), if $(this) wouldn't be used there, is there a easy way of achieving the same effect?
Thanks!

$(this) refers to the the jQuery element that was clicked. Using $(this) is a surefire way to ensure you're referencing the element that was the user interacted with. Unfortunately there is no good way to ensure that you're referencing the element you interacted with without using $(this)

First let's start with what this means. In JavaScript, any function can be bound so that this refers to an arbitrary thing (object, number, string, etc.) inside of the function when it's called (refer to Function.bind). In general there are no assurances of what this will refer to inside of an arbitrary function; you'll have to read the documentation/source code or test for yourself.
When you call click(), jQuery is binding this in your callback function to a target element in the matched set. When you say $(this) (or jQuery(this)), you're simply wrapping the element with a jQuery "wrapper".
As for alternatives, jQuery will pass the event object to your callback, and you can access the target through that:
$("#slideshow-nav a").click(function(evt){
console.log($(evt.target)); //I think just using "$(this)" is easier!
});

See jQuery $(this) vs this.
$("#slideshow-nav a").click(function(){
$("#slideshow-nav a").removeClass("active");
$(this).addClass("active");
});
When the handler function you passed to $("#slideshow-nav a").click() is called, this is bound to the element that fired the event. You then pass this to $() to construct a jQuery object around that element, so you can use jQuery's addClass() on it. You could accomplish the same thing by replacing that line with this.classList.add("active"), to use the non-jQuery way to do the same thing.
Long story short, you use $(this) when this is bound to some element and you want to use jQuery methods on that element.
So, what this code ultimately does is:
Remove the class "active" from all elements matching the selector #slideshow-nav a.
Add the class "active" to the element receiving the event (the clicked element).
In this manner, any previously "active" element is "deactivated", and the clicked one is "activated".

Per minitech's comment, $(this) refers to one of the 'a' elements in the slideshow-nav DOM element, specifically the one that was clicked.
$("#slideshow-nav a").click(function(){
// $("#slideshow-nav a") refers to an array of links in slideshow-nav
$("#slideshow-nav a").removeClass("active");
// $(this) refers just to the specific link that was clicked
$(this).addClass("active");
});
This is best practice AFAIK. Is there some reason you do not want to use $(this)?

Related

jQuery: Add Sibling of Parent to Current Matched Elements

I'm trying to - in one line - remove the parent element of a clicked element and the parent's lone sibling element. This is my two-liner solution here:
$(document).ready(function() {
$('.close').click(function() {
$(this).parent().siblings('.sibling').remove();
$(this).parent().remove();
});
});
Here's a working fiddle. I'm looking to avoid navigating the DOM twice since I've already found the parent of the clicked element when I remove the sibling, there's no reason I should be doing it again. I'm aware that I could wrap both the parent and sibling in an element and just remove that super element, but at this point I'd like to avoid that as well.
I've looked into using jQuery's .add() function, but I can't seem to get that to work. Thanks for your help!
You're looking for .addBack():
$(this).parent().siblings('.sibling').addBack().remove();
Demo
andSelf is an equivalent to .addBack() for jQuery < 1.8
With .add(), you would have to store the parent in a variable to avoid traversing to it twice:
var $father = $(this).parent();
$father.siblings('.sibling').add($father).remove();
//one-liner without storing in a variable would traverse the DOM twice:
$(this).parent().siblings('.sibling').add($(this).parent()).remove();
As you can see, the addBack method is more practical in this case.
In case the element's parent and the parent's sibling are the only elements inside their parent, you can also use:
$(this.parentNode.parentNode).empty();
Demo
The native parentNode property is a bit faster than jQuery's .parent() method. It is up to which to use.
Note that such small traversing has very little overhead either way. Your original code and these versions have very little difference performance-wise.

jQuery on() method - which way to use is better for performance?

Is it better to attach the on() event to the document or a closer parent?
Note: Initially this question had another aspect and a different topic. It became obsolete really quickly (typo in the source code)
The best key for performance using jQuery is to use an id as the initial identifier. For example:
$('#my_id').on('click', 'tag.my_class', function () {
...
});
This allows jQuery to go straight to the container, and then begin trawling from there.
if you bind the "on" event to the closest parent will produce exactly what are you looking for, click function will works fine even if it is appended to document, but in future if you append any elements with class "clickable" will also get binded. so its always good practice to append the "on" event to closest parent rather than whole document.
if you want more specific you can use
$("ul.media-grid").on('click', 'li.clickable', function () {
alert("works")
});
as it will get the ul with the class "media-grid" and appends the event to the li's with class "clickable"

How "this" works in jQuery

Can somebody please explain how "this" works in jQuery. I tried to find some information on the net, but because "this" is used a lot in his usual meaning I couldnt find anything good.
I would like to be able to change the background of a list element (<li>) onclick without giving each list element an id.
$('li').on('click.namespace', function() {
console.log(this); /* this is a reference to the DOM
element you clicked */
console.log($(this)); /* this is a jQuery reference to the
DOM element you clicked */
/* using jQuery reference you can change the background in this way */
$(this).css('background-image', 'url(...)');
});
$("li").click(function() {
$(this).css("background-color", "red");
});
Here is an example. $(this) refers to the JQuery object, this refers to the regular DOM object that was clicked on.
Did you find the click() documentation? It shows how you should use the click handlers and it has examples that even use $(this).
Here's an example:
$('li').click(function() {
$(this).attr("class", "clicked");
});
When one clicks on an item, this takes the value of the item being clicked on, that is the DOM element. $(this) gives you access to the jquery API.
If you set the onclick event on the li you can use $(this) to get the jquery object of the li, and then add a class eg. $(this).addClass("newBackground").
jQuery is kind enough to set the context of your function to the thing you're interesting in. In this case the <li> in question. But this is still a naked DOM element, you need to wrap it with $() to use jQuery methods on it.
$('li').on('click', function() {
$(this).css({background:'red'});
});
Sometimes you have to use a bound function (see jQuery.proxy()) as an event handler, in these cases you can access the current element differently, instead of this, you can use the event.currentTarget property, see http://api.jquery.com/event.currentTarget/

What is the difference between "$(this)" and "this"?

I was reading the http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery. And got confused with use of this in these 2 code segments.
$(document).ready(function() {
$("#orderedlist").find("li").each(function(i) {
$(this).append( " BAM! " + i );
});
});
$(document).ready(function() {
// use this to reset several forms at once
$("#reset").click(function() {
$("form").each(function() {
this.reset();
});
});
});
When do we need $(this) and this? And what is the difference between them? Thanks in advance.
this refers to the DOM element itself; $(this) wraps the element up in a jQuery object.
In the first example, you need $(this) because .append() is a jQuery method.
In the second example, reset() is a JavaScript method, so no jQuery wrapper is needed.
this by itself is just a regular object.
$(this) takes this and adds the jQuery wrapper so you can use the jQuery methods with the object.
this refers to a DOM object. So reset() is a function of a form DOM object. append() on the other hand is a jQuery method so it has to be called by a jQuery object, hence the $(this).
When you surround this with $, you get a jQuery object back representing that DOM object.
Generally in jQuery, this will be an instance of the DOM element in question, and $(this) builds a jQuery object around this which gives you the usual jQuery methods like each() and val().
you only need $(this) if you are following it with a jquery function on the same line of code.
ex: $(this).find(...); $(this).val(); etc
or else you only need this.

event.target points to a child element

When a user clicks on a <li>-element or on a child element of it, I want to add a class to this <li>-element.
This works fine, but for performance enhancement I decided to bind this event to the <ul>-element, so unbinding and binding this event is much faster in a list consisting of 1000 <li>-elements. The only change I thought I had to make was to replace this with event.target BUT event.target can also refer to a child element of a list item or even to a grandchild.
Is there an easy way to check this target element is part of a list item or do I need to walk the path from event.target till I reach a <li> element?
This is what I had before I decided to bind an event to the <ul> tag, which works but is not fast enough:
$('#list li').mousedown(function(){
$(this).addClass('green');
});
And this is what I have now which doesn't work properly, mousedown on a child element doesn't give the <li> another classname:
$('#list').mousedown(function(event){
if(event.target.nodeName == 'LI'){
$(event.target).addClass('green');
}
});
I wonder if my second way to achieve this is faster if there is not a simple solution to check if that target element is part of a list item...
Well, you could do all of this with the jQuery on tool:
$('#list li').on('mousedown', function() {
$(this).addClass('green');
});
You can read about what on does here: http://api.jquery.com/on/
You need to check if there is a LI tag in the parents of the target element.
All of the common frameworks have a way of determining this, it is up() in prototype, ancestor() in YUI3, and looking at the JQuery docs, it seems like it has a parent(), and parents() function that you can use for this.
See: http://docs.jquery.com/Traversing
Haven't used JQuery, but it I assume checking for $(event.target).parent('li') is the answer.

Categories

Resources