【问题标题】:How to use jQuery in Firefox Extension如何在 Firefox 扩展中使用 jQuery
【发布时间】:2010-10-04 05:43:27
【问题描述】:

我想在 firefox 扩展中使用 jQuery, 我像这样在 xul 文件中导入了库:

<script type="application/x-javascript" src="chrome://myExtension/content/jquery.js"> </script>

但是 $() 函数在 xul 文件中不被识别,jQuery() 也不被识别。

我搜索了这个问题并找到了一些解决方案,但没有人与我合作: http://gluei.com/blog/view/using-jquery-inside-your-firefox-extension http://forums.mozillazine.org/viewtopic.php?f=19&t=989465

我还尝试将“content.document”对象(引用“document”对象)作为上下文参数传递给 jQuery 函数,如下所示:

$('img',content.document);

但仍然无法正常工作, 有人遇到过这个问题吗?

【问题讨论】:

  • 我提供赏金,有趣
  • 详细阅读有关在 firefox 扩展中安全使用 jquery 的详细信息,而不会与其他扩展和其他 XUL 组件(如工具栏按钮等)发生冲突:meherranjan.com/blog/…

标签: javascript jquery firefox firefox-addon


【解决方案1】:

由@sunsean does not work as expected when it comes to handling multiple loads 得出当前的最佳答案。该函数应正确关闭文档并避免全局状态。

另外,您必须致电jQuery.noConflict(true) 才能真正避免与其他插件发生冲突!

这就是我要写它的人(再说一次,我会像瘟疫一样避免使用 jquery(在附加组件中)......)。 首先覆盖XUL

<?xml version="1.0"?>
<overlay id="test-addon-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script type="text/javascript" src="jquery.js"/>
  <script type="text/javascript" src="overlay.js"/>
</overlay>

然后是覆盖脚本:

// 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 的副本,就可以了。

【讨论】:

    【解决方案2】:

    代替

    $('img',content.document);
    

    你可以试试

    $('img',window.content.document);
    

    在我的情况下它有效。

    【讨论】:

      【解决方案3】:

      以下解决方案使在 contentScriptFile 中使用 jQuery 成为可能 (针对 1.5 Addon-sdk)

      在你的 main.js 中:

      exports.main = function() {
          var pageMod = require("page-mod");
      
          pageMod.PageMod({
                include: "*",
                contentScriptWhen: 'end',
                contentScriptFile: [data.url("jquery-1.7.1-min.js") , data.url("notifier.js") ,   data.url("message.js")],
                onAttach: function onAttach(worker) {
                   //show the message
                   worker.postMessage("Hello World");
                }
          });
      
      };
      

      在你的 message.js 中:

      self.on("message", function(message){
          if(message !== "undefined"){
             Notifier.info(message); 
          }
      });
      

      您需要注意的一些陷阱:

      • contentScriptFile 数组的顺序。如果将 message.js 放在第一位:jQuery 将不会被重新配置。
      • 不要在data.url 中放置http:// url(这不起作用)!
      • 所有的 javascript 文件都应该在 data 文件夹中。 (只有 main.js 应该在 lib 文件夹中)

      【讨论】:

        【解决方案4】:

        我使用以下example.xul:

        <?xml version="1.0"?>
        <overlay id="example" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
        <head></head>
        <script type="application/x-javascript" src="jquery.js"></script>
        <script type="application/x-javascript" src="example.js"></script>
        </overlay>
        

        这是example.js

        (function() {
            jQuery.noConflict();
            $ = function(selector,context) { 
                return new jQuery.fn.init(selector,context||example.doc); 
            };
            $.fn = $.prototype = jQuery.fn;
        
            example = new function(){};
            example.log = function() { 
                Firebug.Console.logFormatted(arguments,null,"log"); 
            };
            example.run = function(doc,aEvent) {
                // Check for website
                if (!doc.location.href.match(/^http:\/\/(.*\.)?stackoverflow\.com(\/.*)?$/i))  
                    return;
        
                // Check if already loaded
                if (doc.getElementById("plugin-example")) return;
        
                // Setup
                this.win = aEvent.target.defaultView.wrappedJSObject;
                this.doc = doc;
        
                // Hello World
                this.main = main = $('<div id="plugin-example">').appendTo(doc.body).html('Example Loaded!');
                main.css({ 
                    background:'#FFF',color:'#000',position:'absolute',top:0,left:0,padding:8
                });
                main.html(main.html() + ' - jQuery <b>' + $.fn.jquery + '</b>');
            };
        
            // 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);
        
        })();
        

        【讨论】:

        • 这也不起作用,如果你知道任何使用 jQuery 的扩展,请给我它的名字来检查代码。
        • 我添加了一个更完整的示例。检查并查看这是否适合您。
        • 这种方法是绝对不合适的,因为当你从溢出加载 jquery 时,jQuery 和 $ 2 个对象是为整个窗口定义的,可能会导致与其他扩展的冲突。虽然您可以使用 jquery.noconflict 和函数范围来隐藏它,但可以异步加载覆盖。在我可以使用 jquery.noconflict 之前,仍然有可能已经定义了另一个 firefox 的扩展并在窗口上使用了 jQuery 和 $
        • 延迟函数的作用是什么?
        • 这个答案有多个缺陷。但是我觉得编辑它来修复它太激进了。而是stackoverflow.com/a/23776848/484441
        【解决方案5】:

        mozillaZine 论坛中有一篇优秀的文章逐步描述了这一点:http://forums.mozillazine.org/viewtopic.php?f=19&t=2105087

        我还没有尝试过,所以我犹豫在此处复制信息。

        【讨论】:

          【解决方案6】:

          我认为这就是 Eric 所说的,但您可以直接从 URL 加载 Javascript。

          javascript:var%20s=document.createElement('script');s.setAttribute('src','http://YOURJAVASCRIPTFILE.js');document.getElementsByTagName('body')[0].appendChild(s);void(s);
          

          我假设您希望您的扩展程序加载 JQuery 以便您可以轻松地操作页面元素?我公司的实验室在此处直接使用 Javascript 执行此操作:http://parkerfox.co.uk/labs/pixelperfect

          【讨论】:

          • 我知道如何将库注入到页面的 DOM 中,但问题是我无法在页面加载时将扩展的所有功能注入到 DOM 中。这就是为什么我希望所有功能都在扩展文件夹中
          【解决方案7】:

          这可能是不好的做法,但您是否考虑过将其包含在内?

          【讨论】:

          • 我没有尝试过,但我认为它与将它包含在脚本标签中没有什么不同。我还是会试试的
          • 如果您这样做,他们将不会批准您的扩展。您必须包含未经修改的原始库文件,Mozilla 审批者将验证 MD5/SHA 校验和是否匹配。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-10
          • 2021-11-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多