jvcoach23
jvcoach23

Reputation: 3037

jQuery, and using 'this'

I'm trying to figure out how, in jQuery, to word this; I've read over and over again how using this is the proper way to do it when you are going to be performing something on the same element, instead of calling out to it multiple times.

So let's say I have this function:

function fadeDiv1() {
    $(function () {
        $("[id$=lblFadeDiv]").text("aldkfjalfjalsdjf");
        $("[id$=lblFadeDiv]").fadeIn('slow').delay(5000).fadeOut('slow');
    });
};

Making two calls using the $("[id$=lblFadeDiv]") I've read is not the way to do it. That instead we should use this, but all the examples I've seen are on some event. So two questions:

  1. First, is it true that I should be using this, and
  2. Second how would I go about doing that?

Upvotes: 0

Views: 72

Answers (5)

skobaljic
skobaljic

Reputation: 9614

Using this in function to access a DOM element is only possible if the function was raised by Javascript event.

Inside an event handler, this references the current element.

But it makes sense to use it only if element(s) contains crucial, specific data we need to execute the function. This also includes the element's position inside the DOM tree, its siblings, parents, etc.

Here is a simple example (also Fiddle):

$(document).on('mouseenter', '[data-note]', showNote);

function showNote() {
    var thisDiv = $(this);
    var thisNote = $('<div class="note">' + thisDiv.data('note') + '</div>');
    thisDiv.append(thisNote);
    thisNote.fadeIn().delay(1000).fadeOut('normal', function () {
        thisNote.remove();
    });
};

$('p').clone().appendTo('body');
body {
    font-family: sans-serif;
}
[data-note] {
    position: relative;
    display: inline-block;
    color: blue;
}
.note {
    display: none;
    background: none rgba(255, 255, 255, .8);
    position: absolute;
    right: -10px;
    top: 10px;
    padding: 5px;
    border: 1px solid yellow;
    color: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>This is some text <span data-note="Hallo there!">mouse over me</span> or <span data-note="How are you doing!">try me instead</span>.

Upvotes: 0

Bill Kindig
Bill Kindig

Reputation: 3622

In your case, using this wouldn't work. This would simply refer to the function you've made, which has none of the properties you want to work with.

As far as I understand (I'm no expert), using this is either for when you're in an event and you want to access the object. Or, when you're accessing properties of an object, while within the scope of the object. My terminology is probably not right here, but here's examples.

In an object:

var person = {
    firstName: "John",
    lastName: "Smith",
    fullName: function () {
        console.log(this.firstName + " " + this.lastName);
    }
}

Event listener:

$( "#button" ).click(function() {
     $(this).attr('value', 'changed!');
});

Upvotes: 0

Jeremy Thille
Jeremy Thille

Reputation: 26360

this refers to the element that's being clicked or called.

Let's say (simple example) that you have a button that gets a blue border when clicked :

$("#myButton").click(function(){
  $(this).css("border", "green dashed 2px");
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button id="myButton">Click me</button>

this must be wrapped in a jQuery object in order to respond to jQuery's commands such as .css(.... This is why we use $(this).

Now, what you're looking for is different. You want to avoid calling $("[id$=lblFadeDiv]") twice. That's very simple : you just memorize the selection in a variable.

$lblFadeDiv = $("[id$=lblFadeDiv]")

$lblFadeDiv is a valid variable name ($ can be used in a variable name, it's just a standard character). I like adding $ in front of my jQuery objects, just to know they're jQuery objects and not just srings or numbers.

This way, you search for an element (or many elements) in the DOM and wrap them in a jQuery object just once.

Now it's in memory (it's cached), you can use it multiple times, that's very cheap :

$lblFadeDiv.text("aldkfjalfjalsdjf");
$lblFadeDiv.fadeIn('slow').delay(5000).fadeOut('slow');

There is no clicked element in your context, it's just a function, so this refers just to the function that's being called.

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1074168

I've read over and over again how using this is the proper way to do it when you are going to be performing something on the same element, instead of calling out to it multiple times

That's an argument for using a standard variable, not for using this.

First, is it true that I should be using this, and

Not in this case (see above).

Second how would I go about doing that?

Either using chaining or a variable. Chaining is handy and concise, but can sometimes bit a bit awkward to debug and is not always possible (for instance, if you need to have a statement in the middle of the chain that isn't chainable). A variable is more verbose, but easier to debug, and more flexible.

Chaining:

function fadeDiv1() {
    $("[id$=lblFadeDiv]")
        .text("aldkfjalfjalsdjf")
        .fadeIn('slow')
        .delay(5000)
        .fadeOut('slow');
}

A variable:

function fadeDiv1() {
    var div = $("[id$=lblFadeDiv]");
    div.text("aldkfjalfjalsdjf");
    div.fadeIn('slow');
    div.delay(5000);
    div.fadeOut('slow');
}

And you can mix and match as appropriate, for instance this is perfectly valid:

function fadeDiv1() {
    var div = $("[id$=lblFadeDiv]");
    div.text("aldkfjalfjalsdjf");
    div.fadeIn('slow')
       .delay(5000)
       .fadeOut('slow');
}

Upvotes: 2

Jamiec
Jamiec

Reputation: 136094

You dont have a this in that function, but you are refering to the same selector twice, which means its inefficient to look it up twice. You should just chain your functions together:

$("[id$=lblFadeDiv]").text("aldkfjalfjalsdjf")
                     .fadeIn('slow')
                     .delay(5000)
                     .fadeOut('slow');

In a hypothetical situation where you wanted this to happen when clicking that element, then you could use this:

$("[id$=lblFadeDiv]").on('click',function(){
    $(this).text("aldkfjalfjalsdjf")
                     .fadeIn('slow')
                     .delay(5000)
                     .fadeOut('slow');

});

Upvotes: 0

Related Questions