tags:

views:

109

answers:

4

A common issue I have is getting confused what $(this) is referring to.

I often will try to give it some odd style:

$(this).css("border","10px solid red")

Which helps sometimes.

I'm stumped with the following however. My question can maybe be answered in two ways:

1) is there a universal way to 'see' what $(this) is referring to in any given situation? Perhaps in combination with firebug?

2) more specifically, any idea what $(this) should be referring to in this sample below? I assumed it would have been the input with a class of btnSave but doesn't seem to be:

$(ajaxContainer).find("input.btnSave").click(function(){
    savePanel();
});

function savePanel() {
    $(this).css("border","10px solid red");
};
+8  A: 

1) Use the console in Firebug:

var obj = $(this);
console.log(obj);

2) savePanel() won't have the context correct to use $(this). You could try:

$(ajaxContainer).find("input.btnSave").click(function(){
    $(this).css("border", "10px solid red");
});
richsage
thanks! Two answers for the price of one. I appreciate it.
DA
quick edit: I think that should be console.log, right? (That seems to work).
DA
@DA Yep you're right sorry, I always get them confused! I'll edit the post now :-)
richsage
+4  A: 

First question (using Firebug):

  1. Place a breakpoint somewhere in the context you want to investigate (e.g. inside savePanel() in your example).
  2. When your application hits the breakpoint, add $(this) to the watch panel and expand it to view its properties.
  3. The first property should be "0", which corresponds to the first DOM node matched by the jQuery object (in this case, this).
  4. If you hover over the value for "0", Firebug will highlight that DOM node on the page. If you click the value, Firebug will switch to the HTML tab and scroll to that element.

Second question:

  • Inside of your anonymous function, this will refer to the <input /> element.
  • Inside of savePanel(), this will refer to the window object.

If you want savePanel() to have access to the <input /> element, there are a variety of ways to do it. The simplest in your case would be to pass it in from the anonymous function:

$(ajaxContainer).find("input.btnSave").click(function(){
  savePanel($(this));
});

function savePanel(inputElement) {
  inputElement.css("border","10px solid red");
}
Annabelle
ah! Well, that probably leads to a separate question...how does one attach a function to an elements click event so that when clicked, it'll pass a reference to itself to the function it's calling? (Perhaps that should be a new question here on SO?)
DA
You should be able to pass the event in and access the target of the click. Something like what is explained here: [event.target on jquery.com](http://docs.jquery.com/Events/jQuery.Event#event.target)
spig
thanks, spig. Yea, I should have tried before even asking. To answer my own follow-up question comment in another comment... savePanel($(this));
DA
@DA: The easiest thing to do in your case is probably to make the `<input />` element a parameter to `savePanel()`. I will edit my post with examples.
Annabelle
+1  A: 

In your code sample you run into a classic JavaScript problem with a lost context for this, since calling another function from an anonymous function will lose the context from the anonymous function (read more about it here). When savePanel is called like you do, this will refer to the window object. You can keep the context of this, from the event handler, by using call or apply when delegating the method:

$(ajaxContainer).find("input.btnSave").click(function(){
    savePanel.call(this);
});

// OR

$(ajaxContainer).find("input.btnSave").click(function(){
    savePanel.apply(this, arguments);
});

function savePanel() {
    $(this).css("border","10px solid red");
};
PatrikAkerstrand
A: 

"this" is javascript is often a source of confusion, because it syntactically looks like a variable and therefore implies the idea of passing it around. Actually, "this" is more like a function and always returns current execution context, that is, the context the current function was called for or applied to.

If i'm not mistaken, jquery tries to execute a callback in the context the callback binder was called, that is

 object1.object2.object3.bindSomeCallback(function() {
        object3 will be "this" in the callback
 })
stereofrog