0

I just got into caching my jquery objects but not sure how to properly do it when using (this).

Also the only time I know how to use (this) is when its inside a click object or function so like:

$(".trigger").click(function () {
    if ($(this).hasClass('toggle')) {
        $(this).closest("td").next().find(".clueless > div").slideUp();
        $(this).removeClass('toggle');
    } else {
        $(this).closest("td").next().find(".clueless > div").slideDown();
        $(this).addClass('toggle');
    }
});

so if I wanted to cache the $(this).closest("td").next().find(".clueless > div") the only thing I could think would be:

var $something = $(".trigger").find(this).closest("td").next().find(".clueless > div");
j08691
  • 190,436
  • 28
  • 232
  • 252
mike
  • 689
  • 2
  • 9
  • 23
  • $(".trigger").find(this) should == this – dandavis Jun 25 '14 at 20:48
  • 2
    There's no reason to cache the whole `$(this).foo().bar().baz()...` thing because you're using it only once. – JJJ Jun 25 '14 at 20:49
  • 1
    Also, you can use `.end()` after `.find()` (etc.) instead of calling `.removeClass()` on a new line. – Brad Christie Jun 25 '14 at 20:49
  • 1
    Why don't just cache it like `var el = $(this).closest("td").next().find(".clueless > div")` but as someone mentioned, if you are only using it once you don't need to cache it. Only one of the statement in if or else will trigger. I guess you could cache it if you want to save a few characters. It would make more sense to cache `$(this)` inside of your click handler – Huangism Jun 25 '14 at 20:51
  • Also, I'm not really sure what the question is. What does "when nothing is selected" mean? Is the click event the actual use case? – JJJ Jun 25 '14 at 20:52
  • 1
    @Juhana There's actually very good reasons to do so. Stay DRY and improve readability. – plalx Jun 25 '14 at 20:53
  • @plalx Granted, that is a good reason. – JJJ Jun 25 '14 at 20:54
  • So ya im using the class .trigger on a bunch of elements that will be independently opened and closed so to improve performance I want to cache the selection. Thanks all! I dont know why I didnt think to put it inside the click function – mike Jun 26 '14 at 07:55

3 Answers3

1

Not sure exactly what you're trying to achieve but you can cache $(this) whenever it has context.

$(".trigger").click(function () {
    var $trigger = $(this);
    if ($trigger.hasClass('toggle')) {
        $trigger.closest("td").next().find(".clueless > div").slideUp();
        $trigger.removeClass('toggle');
    } else {
        $trigger.closest("td").next().find(".clueless > div").slideDown();
        $trigger.addClass('toggle');
    }
});
Terry
  • 13,683
  • 8
  • 52
  • 78
1

If you want to cache $(this).closest("td").next().find(".clueless > div") then

$(".trigger").click(function () {
    var el = $(this).closest("td").next().find(".clueless > div");
    if ($(this).hasClass('toggle')) {
        el.slideUp();
        $(this).removeClass('toggle');
    } else {
        el.slideDown();
        $(this).addClass('toggle');
    }
});

I assume this is what you are going for, it would make sense to cache $(this) since you are using it multiple times

var $this = $(this);

would do it

Huangism
  • 15,324
  • 5
  • 45
  • 64
  • @SeanKendle that's an opinion and I feel fine, getting downvoted usually presents an opportunity to learn – Huangism Jun 25 '14 at 21:02
  • wow im an idiot I cant believe I didnt think to put it inside the click function thanks! – mike Jun 25 '14 at 21:16
1

I will not completely re-iterate how the this keyword works, but there's an exhaustive explanation here.

In JS when the default this behaviour is not altered

Keeping things simple, to know the object to which the this keyword refers to you can simply look at the left-side of the . in a function invocation.

For example, in myObj.someFunction(), the this keyword within someFunction will point to myObj (that is unless the function has been bound using Function.prototype.bind).

If the function is not invoked on an object, such as someFunction(), then this will point to the global object which is window in browsers.

This is also the case within anonymous functions that are passed around, except for addEventListener, which will make sure that the this value within the handler is the object to which the handler was attached.

E.g.

setTimeout(function () { this; /*window*/ }, 10);

document.addEventListener('click', function (e) {  
    e.target; //the clicked DOM element
    this; //the document
});

When this is altered by the API

Using Function.prototype.call or Function.prototype.apply, it is possible to specify the object to which this will point to during a function execution.

Some libraries (e.g. jQuery) are taking advantage of that feature to make this point to an object that is more intuitive, rather than the global object.

E.g.

$('#someEl').on('click', function (e) {
    this; //the DOM element that was clicked (not the jQuery wrapper)
});

When this is altered in such way by the library, there is no other way than looking at the library's documentation to see what this will be.

We can read from jQuery event docs that:

In addition to the event object, the event handling function also has access to the DOM element that the handler was bound to via the keyword this.

Rewriting your function

Now, here's how you could re-write your function:

$(".trigger").click(function () {
    var $this = $(this).toggleClass('toggle'),
        $elementToSlide = $this.closest("td").next().find(".clueless > div"),
        isToggled =  !$this.hasClass('toggle'),
        slideBehavior = isToggled? 'slideUp' : 'slideDown';

    $elementToSlide[slideBehavior]();
});
Community
  • 1
  • 1
plalx
  • 39,329
  • 5
  • 63
  • 83