2009-05-05 11 views
0

私は以前のjsコードをよりOOPスタイルに移行しました。ここにコードがあります。mousedownの後にmousemoveイベントをプロトタイプに追加できないのはなぜですか?

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); 

でマウスダウンした後のMouseMoveイベントを追加することができませんでした。しかし、私は

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

のようにインラインスタイルを記述する場合、それはOKです。それは2つのコードが同じことをするように見えます。なぜ違いがありますか?ありがとう!


編集、

は2泊のための闘争の後、私は最終的に問題を解決しました。あなたのenlightingのために感謝johnvey。

このエラーはにあります。このというキーワードです。オブジェクトの場合、これはオブジェクト自体ではなくウィンドウを指します。解決策は、最初にグローバルパラメータ私(私= this)を定義しました。今は大丈夫です。

答えて

2

これは、この「キー」がクロージャ内でどのようにスコープされているかに関する、古典的なJavascriptの不具合ブロックです。例示する:

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 

が実際のmain()オブジェクトに関連付けられてい呼び出し時に。関数クロージャ内のthisキーワードを使用して

1)避けてください:

は、一般的にこれに対処するには2つの方法があります。このようにコードを修正するには、イベントバインディングをカスケードするのではなく、1つの場所ですべて収集するだけで、 'displaydown()'と 'displaymove()'の両方から 'this'参照を削除します:

または

2)定義時間にスコープをバインドする関数を使用します。ここ

// 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"; 
    } 
} 

重要な変更は次のとおりです:私は説明するためにPrototypeライブラリーからバインド()メソッドを上げてきたあなたはdisplaymove()を呼び出すときに」、基本的に言う

this.displaymove.bind(this) 

、再現在のEventオブジェクトではなく、 'this'というキーワードを元のスコープコンテキストにスコープします。

+0

こんにちは、johnvey ありがとう!私は2番目の方法として行う必要があると思います。このステップでエラーが発生します。私はIE.6を使用しています。これが理由ですか? – unigogo

+0

IE6は問題ではありません。あなたが得ているエラーは何ですか? 大きな質問として、あなたは何をしようとしていますか?別のイベントハンドラの内部からaddEvent()を呼び出すことは、同じハンドラを何度も何度も繰り返してしまうため、うまくいきません。 – johnvey

+0

johnvey、 最終的に、あなたのコードでエラーが見つかりました。 addEvent(document、 'mousedown'、this.displaydown);縛られるべきである。またはmousedownの範囲内のこれはウィンドウです。私はちょうど簡単に読み込むためにスライダに取り組んだ。 http://www.pagecolumn.com/webparts/sliders.htm – unigogo

関連する問題