Как использовать jQuery в расширении Firefox
Я хочу использовать 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(который refrences объект document) в качестве параметра контекста функции jQuery следующим образом:
$('img',content.document);
но все еще не работает,
кто-нибудь сталкивался с этой проблемой раньше?
Ответы
Ответ 1
Я использую следующий 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);
})();
Ответ 2
Следующее решение позволяет использовать jQuery в contentScriptFile
(Targeting 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");
}
});
};
В вашем сообщении .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
В форумах mozillaZine есть отличная статья, которая описывает это шаг за шагом: http://forums.mozillazine.org/viewtopic.php?f=19&t=2105087
Я еще не пробовал, хотя поэтому не стесняюсь дублировать информацию здесь.
Ответ 4
Я думаю, что это то, о чем говорил Эрик, но вы можете загрузить 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
Ответ 5
Выводит текущий верхний ответ @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>
И затем наложение script:
// 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, и должно быть хорошо идти.
Ответ 6
Это может быть плохая практика, но вы считали ее включенной?
Ответ 7
Вместо
$('img',content.document);
вы можете попробовать
$('img',window.content.document);
В моем случае это работает.