繁体   English   中英

为什么在原型中的mousedown之后无法添加mousemove事件?

[英]Why I could not add mousemove event after mousedown in prototype?

我会将以前的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";
});

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


编辑,

经过2个晚上的奋斗,我终于解决了这个问题。 感谢johnvey的启发。

错误发生在关键字上。 如果是对象,则是指窗口而不是对象本身。 解决的方法是在开始时定义全局参数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()对象。

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

1)避免在函数闭包中使用'this'关键字。 为了以这种方式修复您的代码,我将简单地将所有事件绑定收集在一个位置,而不是级联它们,从而从“ 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()方法来说明:

// 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对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM