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