2

How can I forward the this scope refering to a element that is calling event listener?

exemple:

<input type=button value="Foo" id=mybutton>

addEvent('mybutton','touchstart', function(){
    if(window['touchmoved']==false)
    hover(); 
});


function hover(){
    this.value //undefined
}
Vitim.us
  • 20,746
  • 15
  • 92
  • 109
  • possible duplicate of [Javascript: how to set "this" variable easily?](http://stackoverflow.com/questions/456967/javascript-how-to-set-this-variable-easily) – Felix Kling Dec 18 '11 at 23:32

3 Answers3

7

Use the JavaScript Function.call or Function.apply methods:

addEvent('mybutton','touchstart', function(){
    if(window['touchmoved']==false)
        hover.call(this); // `this` of the called hover points to this `this`
});
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • 1
    To anticipate on a possible further question: If you want to pass a parameter on top of `this`, use: `hover.call(this, "something")`, which invokes `hover("something")` (this = this). – Rob W Dec 18 '11 at 22:39
3

Use fn.call() or fn.apply() to set what you want the value of this to be. See references for call or apply at MDN.

addEvent('mybutton','touchstart', function(){
    if(window['touchmoved']==false) {
        hover.call(this); 
    }
});

Both .call() and .apply() allow you to specify what you want the this pointer to be in the called function.

.call() lets you pass specific additional arguments that you want the called function to receive like this:

fn.call(this, true, "foo")`

.apply() is used when the arguments you want to pass to the called function are in an array and you just pass the array of arguments like this:

var args = [true, "foo"];
fn.apply(this, args);

.apply() is often used with the built-in arguments object to pass the existing arguments on to the called function (though there are other reasons to use it too):

fn.apply(this, arguments);
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Call and Apply are pretty much identical - apart from Apply requires a 2nd parameter - Call does not :) So use Call for when you don't need to assign anything else but this, and when you need to assign other values, use Apply. – Stuart.Sklinar Dec 18 '11 at 22:39
  • 1
    @Stuart.Sklinar: The second argument isn't required for `.apply`. See step 2 of [15.3.4.3 Function.prototype.apply \(thisArg, argArray\)](http://es5.github.com/#x15.3.4.3). Unless you know of a particular implementation issue? – RightSaidFred Dec 18 '11 at 22:50
  • I take it back - I read somewhere that it was required - but I stand corrected - thanks for the link! – Stuart.Sklinar Dec 19 '11 at 10:02
0

You could use the function.Call() method on your hover() method which will call the hover method.

the Call method's first parameter is a value which should be assigned to this in the calling method.

for instance:

addEvent('mybutton','touchstart', function(){
if(window['touchmoved']==false)
{

}
    hover.call(this); 
});


function hover(){
    //this = touchstart event
}
Stuart.Sklinar
  • 3,683
  • 4
  • 35
  • 89
  • 2
    `.call()` is definitely _not_ asynchronous. (For that matter callbacks in general aren't inherently asynchronous, though many async processes use a callback mechanism.) – nnnnnn Dec 18 '11 at 22:55
  • @nnnnnn by the way, the only way that I know to invoke something assynchronous is using `setTimeout` and `setInterval` there's any other way? – Vitim.us Dec 19 '11 at 02:23
  • @Vitimtk - An Ajax call is a good example, typically (but not necessarily) with a specified callback. You can load script files async too. Note that (pre web workers, anyway) all JS runs in the one thread, so async code isn't running at the same time, it gets queued for when the current block completes. – nnnnnn Dec 19 '11 at 02:40
  • but the call is not really assynchronous, just is a event fired on onchangestate (just the data download is assync), I'm wondering how to call a function by another function assynchronous, so `setTimeout(func2,1);` is the only way to call another function without stoping the acctual scope. – Vitim.us Dec 19 '11 at 03:03