简体   繁体   English

Firefox扩展上的选项卡独立jQuery

[英]Tab independent jQuery on Firefox extension

I'm developping a Firefox based on jQuery as described in this Answer here . 我正在开发基于jQuery的Firefox,如此处的“ 答案”中所述。

After implementing the example provided in the answer, eveything works fine, but the problem is the code between Firefox Tabs is somehow linked, and example.doc always refers to the last opened tab. 实现答案中提供的示例后,一切工作都很好,但是问题是Firefox Tabs之间的代码以某种方式链接在一起,而example.doc始终引用最后打开的选项卡。

  • Opened tab1 : the plugin-example has been added and to the current page. 已打开tab1: plugin-example已添加到当前页面。
  • this.doc refers to tab1. this.doc指向tab1。
  • Oepened tab2: the plugin-example has been added to to current page (tab2). tab2已消失:该plugin-example已添加到当前页面(tab2)。
  • this.doc now refers to tab2 this.doc现在引用了tab2
  • back to viewing tab1 : this.doc still refers to tab1. 返回查看tab1: this.doc仍然引用tab1。
  • clicking on plugin-example on tab1 will act on the plugin-example in tab2 instead. 点击plugin-example对TAB1将作用于plugin-example在TAB2代替。

How can I make my code independent between tabs? 如何使我的代码在选项卡之间独立?

Here is an excrept from the code: 这是代码的摘录:

(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);

})();

Your code (overlay script) will only run once per window, not once per tab. 您的代码(覆盖脚本)将仅在每个窗口运行一次,而不是每个选项卡运行一次。 So there is only one example instance per window. 因此,每个窗口只有一个example实例。 And hence example.doc will be set to whatever dispatched DOMContentLoaded last. 因此example.doc将被设置为最后分发的DOMContentLoaded

Your function should properly close over the document and avoid global state. 您的函数应正确关闭文档,并避免处于全局状态。 This is who I would write it (then again, I would avoid jquery (in add-ons) like the plague...) 这就是我要写的人(再说一次,我会避免像瘟疫一样使用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);
})();

Here is a complete add-on as a gist . 这是一个完整的附加要点 Just drop in a copy of jquery and it should be good to go. 只需放入jquery的副本,就可以了。

PS: Reposted this at in the jquery in extensions question PS: 在扩展问题中的jQuery中重新发布了

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM