gpt4 book ai didi

javascript - 为什么原型(prototype)中的 mousedown 之后无法添加 mousemove 事件?

转载 作者:行者123 更新时间:2023-12-02 20:47:29 25 4
gpt4 key购买 nike

我会将以前的 js 代码移至更多 OOP 风格。这是代码。

function addEvent( obj, type, fn ) {
if ( obj.attachEvent ) {
obj['e'+type+fn] = fn;
obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
obj.attachEvent( 'on'+type, obj[type+fn] );
} else
obj.addEventListener( type, fn, false );
}

function test() {

}

test.prototype = {
init: function () {

addEvent(document, 'mousedown', this.displaydown);

},

displaydown : function(e){
document.getElementById('mydiv').innerHTML = "down";
addEvent(document, 'mousemove', this.displaymove);
},

displaymove : function(e){
document.getElementById('mydiv').innerHTML = "move";
}
}

var test0 = new test();

test0.init()

我无法在 mousedown 后添加 mousemove 事件

addEvent(document, 'mousemove', this.displaymove);

但是如果我写像这样的内联样式

addEvent(document, 'mousemove', function(e){
document.getElementById('mydiv').innerHTML = "move";
});

没关系。看起来这两个代码做了同样的事情。为什么会有差异?谢谢!

<小时/>

编辑,

经过两个晚上的努力,我终于解决了这个问题。感谢约翰维的启发。

错误发生在关键字上。如果是对象,this 指的是窗口而不是对象本身。解决办法是我一开始就定义了全局参数me(me = this)。现在好了。

最佳答案

这是一个经典的 Javascript 绊脚石,与“this”键如何在闭包内确定作用域有关。举例说明:

redPrinter = function() {
this.X = 'red';
return function() {
return this.X;
}
}

main = function() {
this.X = 'blue';
var myRedPrinter = new redPrinter();
alert("Red printer returned: " + myRedPrinter());
}

main();

此代码将打印出:

Red printer returned: blue

因为该行中“this”的范围:

return this.X

实际上在调用时与 main() 对象绑定(bind)。

通常有两种方法可以解决此问题:

1) 避免在函数闭包中使用“this”关键字。要以这种方式修复您的代码,我只需将所有事件绑定(bind)收集在一个位置而不是级联它们,从而从“displaydown()”和“displaymove()”中删除“this”引用:

test.prototype = {
init: function () {
addEvent(document, 'mousedown', this.displaydown);
addEvent(document, 'mousemove', this.displaymove);
},

displaydown : function(e){
document.getElementById('mydiv').innerHTML = "down";
},

displaymove : function(e){
document.getElementById('mydiv').innerHTML = "move";
}
}

或者

2) 使用函数柯里化(Currying)在定义时绑定(bind)作用域。我从 Prototype 库中提取了 bind() 方法来进行说明:

// declare the global bind() method for all functions
Function.prototype.bind = function(obj) {
var method = this,
temp = function() {
return method.apply(obj, arguments);
};
return temp;
}

test.prototype = {
init: function () {
addEvent(document, 'mousedown', this.displaydown);
},

displaydown : function(e){
document.getElementById('mydiv').innerHTML = "down";

// note that we bind the method object here
addEvent(document, 'mousemove', this.displaymove.bind(this));
},

displaymove : function(e){
document.getElementById('mydiv').innerHTML = "move";
}
}

这里的重要变化是:

this.displaymove.bind(this)

这基本上是说,“当您调用 displaymove() 时,将关键字“this”的范围重新调整为原始范围上下文,而不是当前的 Event 对象。

关于javascript - 为什么原型(prototype)中的 mousedown 之后无法添加 mousemove 事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/823174/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com