1

我正在使用一个由小部件调用的面板来拍摄存储快照并将其显示在表格中。但是,标记似乎有一些重复。

基本上我有一个用于测试目的的存储项目和几个设置,如开关。每次我单击小部件打开它时,存储项目都会在页面上重复。我可以理解,因为面板不会在显示/隐藏时重新加载。

主要问题是我有一个正常的 jQuery 点击事件来将一些数据发送回存储,这似乎也被重复了。如果我打开和关闭面板 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"
});

测试.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属性检查接收事件时面板是否打开。现在,在面板的整个生命周期中,您只有一个侦听器。

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 回答