1

ウィジェットによって呼び出されるパネルを使用して、ストレージのスナップショットを取得し、それをテーブルに表示しています。しかし、行われているマークアップにいくつかの重複があるようです。

基本的に、テスト用に1つのストレージ項目と、スイッチなどのいくつかの設定があります。ウィジェットをクリックして開くたびに、ストレージアイテムがページに複製されます。パネルは表示/非表示でリロードされないので理解できます。

主な問題は、データをストレージに送り返す通常のjQueryクリックイベントがあり、これも重複しているように見えることです。パネルを6回開閉すると、ワンクリックで6つのイベントが発生します。

これは、リロードするたびにリスナーが増えることを示していますが、リスナーを正しく削除する方法を教えてくれるものが見つかりません。例を参照してください。

コンテンツスクリプト

testPanel = require("sdk/panel").Panel({
    contentURL: data.url("test.html"),
    contentScriptFile: [data.url("test.js")],
    onShow: function() {
        testPanel.port.emit("Loaded")
        testPanel.port.on("clicked", function(){
            console.log('received click')
        });
    }
});

require("sdk/widget").Widget({
    id: "my-widget",
    label: "My Widget",
    panel: testPanel,
        content: "Click here"
});

test.js

var el = document.getElementsByTagName('a')[0];

el.addEventListener('click', function() {
    console.log('clicked');
    self.port.emit("clicked");
});

self.port.on("Loaded", function() {
    $(".wrapper").append('<div>New element</div>');
});

コンソール出力

info: test_addon: Script loaded
info: test_addon: clicked
info: test_addon: received click
info: test_addon: clicked
info: test_addon: received click
info: test_addon: received click
info: test_addon: clicked
info: test_addon: received click
info: test_addon: received click
info: test_addon: received click

誰かが同様の問題を抱えていましたか?

問題が解決しました

の使用法removeListener()は100%明確ではありませんが、匿名関数の代わりにグローバル関数を使用することで、イベントリスナーを削除できますonHide。その後、新しいインスタンスonShowが作成されますが、古いインスタンスは削除されています。ふぅ!

コンテンツスクリプト

function showClick() {
    console.log('received click')
}
testPanel = require("sdk/panel").Panel({
    contentURL: data.url("test.html"),
    contentScriptFile: [data.url("test.js")],
    onShow: function() {
        testPanel.port.emit("Loaded");
        testPanel.port.on("clicked", showClick);
    },
    onHide: function() {
        testPanel.port.removeListener('clicked', showClick);
    }
});
4

1 に答える 1

1

onShow問題を解決したことは知っていますが、通常、メソッドでリスナーを作成する必要はありません。メソッドの外部でリスナーを作成することをお勧めしますonShow。必要に応じて、isShowingプロパティを使用して、イベントの受信時にパネルが開いているかどうかを確認できます。これで、パネルの存続期間中、リスナーは1人だけになります。

function showClick() {
    console.log('received click')
}
testPanel = require("sdk/panel").Panel({
    contentURL: data.url("test.html"),
    contentScriptFile: [data.url("test.js")],
    onShow: function() {
        testPanel.port.emit("Loaded");
    },
    onHide: function() {

    }
});
testPanel.port.on("clicked", function() {
  if (testPanel.isShowing) {
    console.log('received click');
  }
});
于 2013-04-17T15:56:08.833 に答える