2009-05-05 30 views
0

我會把我以前的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() 

我無法

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

鼠標按下後鼠標移動添加事件,但如果我寫內嵌樣式像

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

這是確定的。它看起來2個代碼做同樣的事情。爲什麼有差別?謝謝!


編輯,

2晚鬥爭後,我終於解決了這個問題。感謝johnvey給你的啓發。

錯誤發生在這個關鍵字。在發生對象時,這是指窗口而不是對象本身。解決方案是我在開始時定義了全局參數me(me = this)。現在可以了。

回答

2

這是一個經典的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 

因爲的範圍 '這個' 的行:

return this.X 

實際上是依賴於主()對象在調用時。

通常有2種方法來解決這一:

1)避免使用函數封閉內的 '本' 的關鍵字。爲了以這種方式修復你的代碼,我只需要在一個地方收集所有事件綁定而不是級聯它們,從而從'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在定義時綁定範圍。我從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對象

+0

嗨,johnvey 謝謝!我認爲我需要做第二種方法,但我無法綁定()。此步驟出現錯誤。我使用的是IE.6。這是原因嗎? – unigogo 2009-05-05 06:05:10

相關問題