Javascript 为什么我不能在原型中的mousedown之后添加mousemove事件?

Javascript 为什么我不能在原型中的mousedown之后添加mousemove事件?,javascript,object,events,mousemove,Javascript,Object,Events,Mousemove,我会把我以前的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.ad

我会把我以前的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";
});
没关系。看起来这两个代码做了相同的事情。为什么会有区别?谢谢


编辑

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


错误发生在这个关键字上。对于对象,它指的是窗口而不是对象本身。解决方案是我在开始时定义全局参数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();
// 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";
    }
}
此代码将打印出来:

Red printer returned: blue
因为行中“this”的范围:

return this.X
实际上在调用时绑定到main()对象

通常有两种解决方法:

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

2)使用函数currying在定义时绑定范围。我从Prototype库中提取了bind()方法来说明:

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();
// 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'的作用域重新设置为原始作用域上下文,而不是当前事件对象。

您好,谢谢!我想我需要像第二个方法那样做。但是我无法绑定()。这一步出现错误。我正在使用IE.6。这就是原因吗?IE6不应该是问题所在。你得到的错误是什么?作为一个更大的问题,你想做什么?调用addEvent()从另一个事件处理程序内部进行处理是不好的,因为你会一次又一次地附加同一个处理程序。约翰维,我终于在你的代码中找到了错误。addEvent(文档'mousedown',this.displaydown);也应该被绑定。或者这在mousedown的范围内是窗口。我只是使用了一个滑块以方便加载。