2010-10-13 11 views
5

Ich habe eine Funktion, die ein JQuery-Ereignishandler ist. Da es sich um einen JQuery-Ereignishandler handelt, verwendet es die this-Variable, um auf das Objekt Bezug zu nehmen, auf dem es aufgerufen wird (wie es für diese Bibliothek normal ist).Wie definiere ich `this` in Javascript?

Leider muss ich diese Methode an dieser Stelle manuell aufrufen. Wie mache ich this innerhalb der aufgerufenen Funktion so, als ob sie von JQuery aufgerufen würde?

Beispielcode:

function performAjaxRequest() { 
    //Function which builds AJAX request in terms of "this" 
} 

function buildForm(dialogOfForm) { 
    var inputItem; 
    dialogOfForm.html('...'); 
    dialogOfForm.dialog('option', 'buttons', { 
     "Ok" : performAjaxRequest 
    }); 
    inputItem = dialogOfForm.children(':not(label)'); 
    //Redirect enter to submit the form 
    inputItem.keypress(function (e) { 
     if (e.which === 13) { 
      performAjaxRequest(); //Note that 'this' isn't the dialog box 
            //as performAjaxRequest expects here, it's 
            //the input element where the user pressed 
            //enter! 
     } 
    } 
} 

Antwort

8

Wenn dialog ist das Objekt, das Sie müssen dann this eingestellt werden:

performAjaxRequest.apply(dialog, []); 
// arguments (instead of []) might be even better 

sollte es tun.

Ansonsten in jQuery können Sie rufen Sie einfach die trigger Methode auf dem Element, das Sie this

Say gesetzt haben wollen, zum Beispiel, dass Sie ein click Ereignis geschehen auf einem Knopf haben wollte, und Sie müssen es passiert jetzt. Rufen Sie einfach an:

$("#my_button").trigger("click"); 

Ihre #my_button ‚s click Handler aufgerufen werden, und this wird das #my_button Element eingestellt werden.

Wenn Sie eine Methode mit einem anderen this anrufen müssen ... sagen zum Beispiel mit this auf das jQuery-Objekt bezieht sich, dann werden Sie wollen call oder apply auf Ihre Funktion verwenden.

Chuck und meder bereits Sie Beispiele für jeden gegeben ... aber alles zu haben, alles an einem Ort:

// Call 
my_function.call(object_to_use_for_this, argument1, argument2, ... argumentN); 

// Apply 
my_function.apply(object_to_use_for_this, arguments_array); 

SEE: A List Apart's Get Out of Binding Situations

+0

Angenommen, ich habe keine praktische Referenz auf das tatsächliche Ereignis oder Element, auf dem das Ereignis ausgelöst werden würde. –

+0

@Billy ... Sie möchten also ein variables Ereignis für ein variables Objekt oder eine Gruppe von Objekten auslösen? Wenn ja, wie sieht der allgemeine Code aus? Was weißt du im Moment, wenn du alles auslösen willst, was du auslösen musst? –

+0

Nur die Frage aktualisiert - lassen Sie mich wissen, wenn das es klarer macht. –

10

Sie können die call Methode der Funktion verwenden.

someFunction.call(objectToBeThis, argument1, argument2, andSoOnAndSoOn); 
+1

+1 auf die erste Antwort, die das direkteste Problem beantwortet, das ich gestellt habe. Checked @ Sean's Antwort obwohl einfach, weil es vollständiger ist. –

3

Suchen Sie ..

functionRef.apply(objectContext, arguments); 
+1

+1 - Auch eine gute Antwort, obwohl @ Chucks Antwort direkter tut, was ich suchte. –

0

Gebrauch eine Verschluss heißt dies frühzeitig zu, dass zuweisen; dann kannst du damit machen, was du willst.

var that = this; 
+0

Sehen Sie sich meinen Beispielcode an. Beachten Sie, dass die Ereignis Funktion von zwei Orten aufgerufen wird. Wie schlägst du vor, das mit einer Schließung zu lösen, ohne den Inhalt von "performAjaxRequest" zu duplizieren? –

1

Sie sollten natürlich call() und apply() wie die Leute gesagt haben zu meistern lernen, aber ein kleiner Helfer schadet nie ...

In jQuery gibt es $.proxy.

function proxyFn(fn , scope){ 
    return function(){ 
    return fn.apply(scope,arguments); 
    } 
} 

Anwendungsbeispiele:

var myFunctionThatUsesThis = function(A,B){ 
    console.log(this,arguments); // {foo:'bar'},'a','b' 
}; 

// setTimeout or do Ajax call or whatever you suppose loses "this" 

var thisTarget = {foo: 'bar'}; 
setTimeout(proxyFn(myFunctionThatUsesThis, thisTarget) , 1000 , 'a', 'b'); 

// or... 

var contextForcedCallback = proxyFn(myAjaxCallback , someObjectToBeThis); 
performAjaxRequest(myURL, someArgs, contextForcedCallback); 

Wenn Sie es missbrauchen nicht, dann ist es ein todsicheres Werkzeug nie) mit so etwas wie, in reinem js, können Sie diese niftyness neu erstellen den Rahmen von "this" verlieren.

+0

Sorry, die ursprüngliche Funktion, die ich zur Verfügung gestellt habe, enthielt einen mentalen Lapsus. Es wurde auf die korrekte Version aktualisiert. – Quickredfox