Firefox扩展上的标签独立jQuery

时间:2014-05-20 22:29:29

标签: javascript jquery firefox firefox-addon

我正在开发基于jQuery的Firefox,如Answer here所述。

在实现答案中提供的示例后,eveything工作正常,但问题是Firefox Tabs之间的代码以某种方式链接,example.doc始终引用最后打开的选项卡。

  • 已打开tab1:plugin-example已添加到当前页面。
  • this.doc指的是tab1。
  • Oepened tab2:plugin-example已添加到当前页面(tab2)。
  • this.doc现在指的是tab2
  • 返回查看标签1:this.doc仍然引用标签1。
  • 点击tab1上的plugin-example会改为执行tab2中的plugin-example

如何让我的代码在标签之间独立?

以下是代码的摘录:

(function() {
    jQuery.noConflict();
    $ = function(selector,context) { 
        return new jQuery.fn.init(selector,context||example.doc); 
    };
    $.fn = $.prototype = jQuery.fn;

    example = new function(){};

    example.run = function(doc,aEvent) {
        if (doc.getElementById("plugin-example")) return;
        this.doc = doc;
        this.main = main = $('<div id="plugin-example">').appendTo(doc.body).html('Example Loaded!');
        this.main.click(function() { //<--- added this function
                example.main.html(example.doc.location.href);
        });
        main.css({ 
            background:'#FFF',color:'#000',position:'absolute',top:0,left:0,padding:8
        });
    };
    // Bind Plugin
    var delay = function(aEvent) { 
        var doc = aEvent.originalTarget; setTimeout(function() { 
            example.run(doc,aEvent); 
        }, 1); 
     };
    var load = function() { 
        gBrowser.addEventListener("DOMContentLoaded", delay, true); 
    };
    window.addEventListener("pageshow", load, false);

})();

1 个答案:

答案 0 :(得分:1)

您的代码(覆盖脚本)每个窗口只运行一次,而不是每个标签运行一次。因此每个窗口只有一个example个实例。因此,example.doc将被设置为最后发送的DOMContentLoaded

您的功能应正确关闭文档并避免全局状态。 这就是我要写的人(然后再说一遍,我会避免像瘟疫那样的jquery(附加组件)......)

// Use strict mode in particular to avoid implicitly var declarations
(function() {
  "use strict";

  // Main runner function for each content window.
  // Similar to SDK page-mod, but without the security boundaries.
  function run(window, document) {
    // jquery setup. per https://stackoverflow.com/a/496970/484441
    $ = function(selector,context) {
      return new jq.fn.init(selector,context || document); 
    };
    $.fn = $.prototype = jq.fn;

    if (document.getElementById("my-example-addon-container"))  {
      return;
    }
    let main = $('<div id="my-example-addon-container">');
    main.appendTo(document.body).text('Example Loaded!');
    main.click(function() { //<--- added this function
      main.text(document.location.href);
    });
    main.css({
      background:'#FFF',color:'#000',position:'absolute',top:0,left:0,padding:8
    });
  };

  const log = Components.utils.reportError.bind(Components.utils);

  // Do not conflict with other add-ons using jquery.
  const jq = jQuery.noConflict(true);

  gBrowser.addEventListener("DOMContentLoaded", function load(evt) {
    try {
      // Call run with this == window ;)
      let doc = evt.target.ownerDocument || evt.target;
      if (!doc.location.href.startsWith("http")) {
        // Do not even attempt to interact with non-http(s)? sites.
        return;
      }
      run.call(doc.defaultView, doc.defaultView, doc);
    }
    catch (ex) {
      log(ex);
    }
  }, true);
})();

这是a complete add-on as a gist。只需放入一份jquery副本就可以了。

PS:在jquery in extensions question

中重新发布此信息