0

ボタンがクリックされるたびにマウスクリック(マウスアップ)座標を警告する単純な拡張機能を作成しようとしています。(学習の試み)

拡張機能は正常に機能しており、1つの不具合を除いて正しくセットアップされています。

私のXULファイル:

<?xml version="1.0"?>

    <?xml-stylesheet type="text/css" href="chrome://global/skin/" ?>
    <?xml-stylesheet type="text/css"

href="chrome://mouseclick/skin/mouseclick.css" ?>

<!DOCTYPE overlay SYSTEM
  "chrome://mouseclick/locale/mouseclick.dtd">

<overlay id = "overlay-id" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    <script type="application/x-javascript"
    src="chrome://mouseclick/content/mouseclick.js" />

    <toolbarpalette id="BrowserToolbarPalette">
    <toolbarbutton id="mouseclick-button" class="mouseclick-class"
                   label="&button.label;" tooltiptext="&tooltip.text;" 
                   oncommand = "mouseClick.display();"/>
  </toolbarpalette>
  <toolbar id="nav-bar">
    <toolbarbutton id="mouseclick-button" class="mouseclick-class"
                   label="&button.label;" tooltiptext="&tooltip.text;"
                   oncommand = "mouseClick.display();"/>
    </toolbar>
</overlay>

私のJSファイル:

if(mouseClick === undefined) {
  var mouseClick = {
    _x : "not yet clicked" ,
    _y : "not yet clicked"
  };
}

mouseClick.handler = function(e) {
  var x = e.pageX !== undefined ? e.pageX : e.clientX;
  var y = e.pageY !== undefined ? e.pageY : e.clientY;
  /*A TEST ALERT
  alert("(" + x + ", " + y + ")"); // a dummy command for testing
  */
  this._x = x;
  this._y = y;
};

mouseClick.display = function() {
    alert("(" + this._x + ", " + this._y + ")");
};

window.addEventListener("mouseup", mouseClick.handler, false);

この問題は、ドキュメント内の任意の場所、または拡張ボタン以外のウィンドウ内の任意の場所をクリックすると、TESTalertコマンドが正しい座標を警告します。

ただし、ボタンをクリックすると(アラートコマンドを再度トリガーするため)、最初のTESTアラートは正しい座標を返します。

しかし、メインアラート、アラート(not yet clicked, not yet clicked)

mouseClick拡張機能のボタンをクリックするたびにオブジェクトがリセットされるのはなぜですか?

4

1 に答える 1

4

拡張機能のボタンをクリックするたびに mouseClick オブジェクトがリセットされるのはなぜですか?

リセットされていません。設定されたことはありません。


問題

イベント ハンドラ内では、 ではなく をthis参照します。オブジェクトを に直接バインドしているため、ハンドラはオブジェクトのコンテキストでは呼び出されません。windowmouseClickwindow

つまり、関数内でthis._x = x;は と同じwindow._x = x;です。myClick._x変更されることはありません。
後で を呼び出すとmouseClick.display()thisその関数内で参照されmouseClick、初期値がアラートされます。

関数は他の値と同じです。オブジェクトのプロパティに割り当てても、魔法のようにそのオブジェクトにバインドされません。何thisを参照するかは、関数が作成されたときではなく、関数が呼び出されたときに決定されます。

MDN はthis非常によく説明しており、quirksmode.org はイベント ハンドラーに照らして説明しています


ソリューション

[MDN]mouseClickを使用してハンドラーを明示的にバインドできます。.bind

window.addEventListener("mouseup", mouseClick.handler.bind(mouseClick), false);

または、代わりに次を呼び出す関数を渡しますmouseClick.handler

window.addEventListener("mouseup", function(event) {
    mouseClick.handler(event);
}, false);
于 2013-01-04T18:08:29.800 に答える