jQuery/javascript events - prototype event handler

こ雲淡風輕ζ 提交于 2019-12-10 12:18:40

问题


The following code doesn't work as I intuitively expect it to:

function MyObject(input) {
   input.change(this._foo);
   this.X = undefined;
}

MyObject.prototype._foo = function() {
   alert("This code is never called");
   // but if it did
   this.X = true;
}

var test_input = $("input#xyz"); // a random, existing input

var m = MyObject(test_input); // attach handler (or try to)

test_input.change(); // trigger event

alert(m.X); // undefined

I'd expect that _foo() would be called (and, if that ever happens, that the this variable in _foo() would be an instantiation of MyObject.

Does anyone know why this doesn't work, and of any alternative pattern for passing an object to an event handler?

Thank you for reading.

Brian


回答1:


As Kenny points out you're missing the new. You also need to make sure that this in _foo refers to the MyObject instance
One way to do it:-

function MyObject( input ) {
    var _this = this;
    input.change( function() {
       // explicitly set the `this` in _foo to `_this`
        _this._foo.call( _this );
    });
   this.X = undefined;
}

MyObject.prototype._foo = function( event ) {
   alert("This is called");
   // and 'this', being 'm', has X set to true
   this.X = true;
   // the textbox must be accessed by 'event.target' not 'this' if you need it
}

var test_input = jQuery("input#xyz"); // a random, existing input

var m = new MyObject(test_input); // attach handler (or try to)

test_input.change(); // trigger event

alert(m.X); // true

P.S You can't avoid using the new operator by leaving it out! :)




回答2:


To create an object in Javascript, use new.

var m = new MyObject(test_input); // attach handler (or try to)



回答3:


This question is kind of old now, but there's another solution. Your problem is as meouw mentioned, you missed the 'new', and the 'this' reference in an event handler will always be the element on which the event was triggered, not the object handling the event.

Since you're using JQuery, there's an easy way to get this to act the way you want. Use the JQuery.proxy method to set the context of the event handler to use your object as 'this'. In your example, you just have to change the line

input.change(this._foo);

to

input.change(jQuery.proxy( this, "_foo" )); 

Give that a try if you run into this problem with JQuery again.



来源:https://stackoverflow.com/questions/3018564/jquery-javascript-events-prototype-event-handler

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!