Как использовать jQuery в расширении Firefox - PullRequest
57 голосов
/ 29 января 2009

Я хочу использовать jQuery внутри расширения Firefox, Я импортировал библиотеку в файл 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» (который ссылается на объект «документ») в качестве параметра контекста в функцию jQuery, например:

$('img',content.document);

но все еще не работает, кто-нибудь сталкивался с этой проблемой раньше?

Ответы [ 7 ]

28 голосов
/ 30 января 2009

Я использую следующее 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);

})();
10 голосов
/ 09 марта 2012

Следующее решение позволяет использовать jQuery в contentScriptFile. (С таргетингом 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 не будет преобразован.
  • Не помещайте http: // url в data.url (это не работает)!
  • Все ваши файлы JavaScript должны быть в папке данных. (только файл main.js должен находиться в папке lib)
3 голосов
/ 08 марта 2011

На форумах mozillaZine есть отличная статья, которая описывает этот шаг за шагом: http://forums.mozillazine.org/viewtopic.php?f=19&t=2105087

Я еще не пробовал, хотя поэтому не решаюсь дублировать информацию здесь.

2 голосов
/ 21 мая 2014

Получается, что текущий топ-ответ @sunsean не работает должным образом, когда дело доходит до обработки нескольких нагрузок . Функция должна правильно закрывать документ и избегать глобального состояния.

Кроме того, вы должны позвонить 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);
})();

Вот полное дополнение в виде сущности . Просто вставьте копию jquery, и все будет хорошо.

2 голосов
/ 30 января 2009

Я думаю, это то, что говорил Эрик, но вы можете напрямую загрузить Javascript из URL.

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

0 голосов
/ 14 июля 2013

вместо

$('img',content.document);

Вы можете попробовать

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

В моем случае это работает.

0 голосов
/ 29 января 2009

Это может быть плохая практика, но вы рассматривали вопрос о включении его в строку?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...