Как я могу использовать jQuery в сценариях Greasemonkey в Google Chrome?

Как некоторые из вас могут знать, Google Chrome поставил некоторые серьезные ограничения на сценарии Greasemonkey.

Chromium не поддерживает @require , @resource , unsafeWindow , GM_registerMenuCommand , GM_setValue или GM_getValue .

Не требуя, я не могу найти способ включить библиотеку jQuery в сценарий Greasemonkey в Google Chrome.

Есть ли у кого-нибудь совет в этом вопросе?

Из «User Script Tip: Использование jQuery – Блог Erik Vold»

 // ==UserScript== // @name jQuery For Chrome (A Cross Browser Example) // @namespace jQueryForChromeExample // @include * // @author Erik Vergobbi Vold & Tyler G. Hicks-Wright // @description This userscript is meant to be an example on how to use jQuery in a userscript on Google Chrome. // ==/UserScript== // a function that loads jQuery and calls a callback function when jQuery has finished loading function addJQuery(callback) { var script = document.createElement("script"); script.setAttribute("src", "//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"); script.addEventListener('load', function() { var script = document.createElement("script"); script.textContent = "window.jQ=jQuery.noConflict(true);(" + callback.toString() + ")();"; document.body.appendChild(script); }, false); document.body.appendChild(script); } // the guts of this userscript function main() { // Note, jQ replaces $ to avoid conflicts. alert("There are " + jQ('a').length + " links on this page."); } // load jQuery and execute the main function addJQuery(main); 

Я написал несколько функций, основанных на сценарии Эрика Вольда, чтобы помочь мне запускать функции, код и другие скрипты в документе. Вы можете использовать их для загрузки jQuery на страницу, а затем запускать код под областью глобального window .

Пример использования

 // ==UserScript== // @name Example from http://stackoverflow.com/q/6834930 // @version 1.3 // @namespace http://stackoverflow.com/q/6834930 // @description An example, adding a border to a post on Stack Overflow. // @include http://stackoverflow.com/questions/2246901/* // ==/UserScript== var load,execute,loadAndExecute;load=function(a,b,c){var d;d=document.createElement("script"),d.setAttribute("src",a),b!=null&&d.addEventListener("load",b),c!=null&&d.addEventListener("error",c),document.body.appendChild(d);return d},execute=function(a){var b,c;typeof a=="function"?b="("+a+")();":b=a,c=document.createElement("script"),c.textContent=b,document.body.appendChild(c);return c},loadAndExecute=function(a,b){return load(a,function(){return execute(b)})}; loadAndExecute("//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js", function() { $("#answer-6834930").css("border", ".5em solid black"); }); 

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

функции

load(url, onLoad, onError)

Загружает скрипт по url адресу в документ. Необязательно, обратные вызовы могут предоставляться для onLoad и onError .

execute(functionOrCode)

Вставляет в документ функцию или строку кода и выполняет ее. Перед их вставкой функции преобразуются в исходный код, поэтому они теряют свою текущую область / закрытие и запускаются под глобальной областью window .

loadAndExecute(url, functionOrCode)

Ярлык; это загружает скрипт из url , затем вставляет и выполняет functionOrCode случае успеха.

Код

 function load(url, onLoad, onError) { e = document.createElement("script"); e.setAttribute("src", url); if (onLoad != null) { e.addEventListener("load", onLoad); } if (onError != null) { e.addEventListener("error", onError); } document.body.appendChild(e); return e; } function execute(functionOrCode) { if (typeof functionOrCode === "function") { code = "(" + functionOrCode + ")();"; } else { code = functionOrCode; } e = document.createElement("script"); e.textContent = code; document.body.appendChild(e); return e; } function loadAndExecute(url, functionOrCode) { load(url, function() { execute(functionOrCode); }); } 

Используйте jQuery, не опасаясь конфликтов , вызывая jQuery.noConflict(true) . Вот так:

 function GM_main ($) { alert ('jQuery is installed with no conflicts! The version is: ' + $.fn.jquery); } add_jQuery (GM_main, "1.7.2"); function add_jQuery (callbackFn, jqVersion) { jqVersion = jqVersion || "1.7.2"; var D = document; var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement; var scriptNode = D.createElement ('script'); scriptNode.src = 'http://ajax.googleapis.com/ajax/libs/jquery/' + jqVersion + '/jquery.min.js' ; scriptNode.addEventListener ("load", function () { var scriptNode = D.createElement ("script"); scriptNode.textContent = 'var gm_jQuery = jQuery.noConflict (true);\n' + '(' + callbackFn.toString () + ')(gm_jQuery);' ; targ.appendChild (scriptNode); }, false); targ.appendChild (scriptNode); } 


Но, для кросс-браузерных скриптов, почему бы вам не воспользоваться хорошей, быстрой, локальной копией jQuery, когда сможете?

Следующее работает как пользовательский скрипт Chrome и сценарий Greasemonkey, и он использует симпатичную локальную копию @require jQuery, если платформа поддерживает ее.

 // ==UserScript== // @name _Smart, cross-browser jquery-using script // @include http://YOUR_SERVER.COM/YOUR_PATH/* // @require http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js // @grant GM_info // ==/UserScript== function GM_main ($) { alert ('jQuery is installed with no conflicts! The version is: ' + $.fn.jquery); } if (typeof jQuery === "function") { console.log ("Running with local copy of jQuery!"); GM_main (jQuery); } else { console.log ("fetching jQuery from some 3rd-party server."); add_jQuery (GM_main, "1.7.2"); } function add_jQuery (callbackFn, jqVersion) { var jqVersion = jqVersion || "1.7.2"; var D = document; var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement; var scriptNode = D.createElement ('script'); scriptNode.src = 'http://ajax.googleapis.com/ajax/libs/jquery/' + jqVersion + '/jquery.min.js' ; scriptNode.addEventListener ("load", function () { var scriptNode = D.createElement ("script"); scriptNode.textContent = 'var gm_jQuery = jQuery.noConflict (true);\n' + '(' + callbackFn.toString () + ')(gm_jQuery);' ; targ.appendChild (scriptNode); }, false); targ.appendChild (scriptNode); } 

Если на странице уже есть jQuery, просто следуйте этому шаблону:

 // ==UserScript== // @name My Script // @namespace my-script // @description Blah // @version 1.0 // @include http://site.com/* // @author Me // ==/UserScript== var main = function () { // use $ or jQuery here, however the page is using it }; // Inject our main script var script = document.createElement('script'); script.type = "text/javascript"; script.textContent = '(' + main.toString() + ')();'; document.body.appendChild(script); 

Есть очень простой способ обойти, включая полную копию скриптов jQuery для Chrome, когда эти сценарии фактически не используют никаких привилегированных функций ( функции GM_ * и т. Д.) …

Просто вставьте сам скрипт в страницу DOM и выполните! Самое приятное то, что этот метод работает так же хорошо и в Firefox + Greasemonkey, поэтому вы можете использовать тот же скрипт для обоих:

 var script = document.createElement("script"); script.type = "text/javascript"; script.textContent = "(" + threadComments.toString() + ")(jQuery)"; document.body.appendChild(script); function threadComments($) { // taken from kip's http://userscripts-mirror.org/scripts/review/62163 var goodletters = Array('\u00c0','\u00c1','\u00c2','\u00c3','\u00c4','\u00c5','\u00c6','\u00c7' ,'\u00c8','\u00c9','\u00ca','\u00cb','\u00cc','\u00cd','\u00ce','\u00cf' ,'\u00d1','\u00d2','\u00d3','\u00d4','\u00d5','\u00d6' ,'\u00d8','\u00d9','\u00da','\u00db','\u00dc','\u00dd' ,'\u00e0','\u00e1','\u00e2','\u00e3','\u00e4','\u00e5','\u00e6','\u00e7' ,'\u00e8','\u00e9','\u00ea','\u00eb','\u00ec','\u00ed','\u00ee','\u00ef' ,'\u00f1','\u00f2','\u00f3','\u00f4','\u00f5','\u00f6' ,'\u00f8','\u00f9','\u00fa','\u00fb','\u00fc','\u00fd' ,'\u00ff').join(''); // from Benjamin Dumke's http://userscripts-mirror.org/scripts/review/68252 function goodify(s) { good = new RegExp("^[" + goodletters + "\\w]{3}"); bad = new RegExp("[^" + goodletters + "\\w]"); original = s; while (s.length >3 && !s.match(good)) { s = s.replace(bad, ""); } if (!s.match(good)) { // failed, so we might as well use the original s = original; } return s; } in_reply_to = {}; function who(c, other_way) { if (other_way) { // this is closer to the real @-reply heuristics m = /@(\S+)/.exec(c); } else { m = /@([^ .:!?,()[\]{}]+)/.exec(c); } if (!m) {return} if (other_way) {return goodify(m[1]).toLowerCase().slice(0,3);} else {return m[1].toLowerCase().slice(0,3);} } function matcher(user, other_way) { if (other_way) { return function () { return goodify($(this).find(".comment-user").text()).toLowerCase().slice(0,3) == user } } else { return function () { return $(this).find(".comment-user").text().toLowerCase().slice(0,3) == user } } } function replyfilter(id) { return function() { return in_reply_to[$(this).attr("id")] == id; } } function find_reference() { comment_text = $(this).find(".comment-text").text(); if (who(comment_text)) { fil = matcher(who(comment_text)); all = $(this).prevAll("tr.comment").filter(fil); if (all.length == 0) { // no name matched, let's try harder fil = matcher(who(comment_text, true), true); all = $(this).prevAll("tr.comment").filter(fil); if (all.length == 0) {return} } reference_id = all.eq(0).attr("id"); in_reply_to[$(this).attr("id")] = reference_id; } } // How far may comments be indented? // Note that MAX_NESTING = 3 means there are // up to *four* levels (including top-level) MAX_NESTING = 3 // How many pixels of indentation per level? INDENT = 30 function indenter(parent) { for (var i = MAX_NESTING; i > 0; i--) { if (parent.hasClass("threading-" + (i-1)) || (i == MAX_NESTING && parent.hasClass("threading-" + i))) { return function() { $(this).addClass("threading-" + i).find(".comment-text").css({"padding-left": INDENT*i}); } } } return function() { $(this).addClass("threading-1").find(".comment-text").css({"padding-left": INDENT}); } } function do_threading(){ id = $(this).attr("id"); replies = $(this).nextAll("tr.comment").filter(replyfilter(id)); ind = indenter($(this)); replies.each(ind); replies.insertAfter(this); } function go() { $("tr.comment").each(find_reference); $("tr.comment").each(do_threading); } $.ajaxSetup({complete: go}); go(); } 

(unapologetically украден из Shog9 на meta.stackoverflow, так как он не перемещает его здесь, и мне нужно удалить мета-сообщение ..)

Простым способом является использование required ключевого слова:

 // @require http://code.jquery.com/jquery-latest.js 

Кроме того, вы можете упаковать свой скрипт с jQuery в расширение Chrome. См . Скрипты содержимого Google Chrome .

Расширения Chrome, в отличие от сценариев Greasemonkey, могут автоматически обновляться.

Простое решение: вырежьте + вставьте содержимое jquery.min.js в начало вашего пользовательского скрипта. Готово.

Я нашел различные проблемы с рекомендуемыми ответами. Решение addJQuery () работает на большинстве страниц, но на многих ошибках. Если вы столкнетесь с проблемами, просто скопируйте + вставьте содержимое jquery в свой скрипт.

Интересно, не можете ли вы полагаться на document.defaultView.jQuery в вашем GM-скрипте ala:

 if (document.defaultView.jQuery) { jQueryLoaded(document.defaultView.jQuery); } else { var jq = document.createElement('script'); jq.src = 'http://jquery.com/src/jquery-latest.js'; jq.type = 'text/javascript'; document.getElementsByTagName('head')[0].appendChild(jq); (function() { if (document.defaultView.jQuery) jQueryLoaded(document.defaultView.jQuery); else setTimeout(arguments.callee, 100); })(); } function jQueryLoaded($) { console.dir($); } 

Другим подходом было бы изменить ваш скрипт для загрузки jQuery вручную. Пример из http://joanpiedra.com/jquery/greasemonkey/ :

 // Add jQuery var GM_JQ = document.createElement('script'); GM_JQ.src = 'http://jquery.com/src/jquery-latest.js'; GM_JQ.type = 'text/javascript'; document.getElementsByTagName('head')[0].appendChild(GM_JQ); // Check if jQuery's loaded function GM_wait() { if(typeof unsafeWindow.jQuery == 'undefined') { window.setTimeout(GM_wait,100); } else { $ = unsafeWindow.jQuery; letsJQuery(); } } GM_wait(); // All your GM code must be inside this function function letsJQuery() { alert($); // check if the dollar (jquery) function works } 

EDIT: DRATS! После тестирования появляется этот код, который не работает, поскольку Google Chrome запускает пользовательские сценарии / расширения в отдельной области / процессе с фактической веб-страницы. Вы можете загрузить код jQuery с помощью XmlhttpRequest, а затем Eval, но вам нужно разместить код на сервере, который позволяет использовать совместное использование ресурсов Cross-Origin с помощью заголовка Access-Control-Allow-Origin: * . К сожалению, NONE из текущих CDN с поддержкой jQuery.

Идеальное расширение для встраивания jQuery в Chrome Console так просто, как вы можете себе представить. Это расширение также вмешивается, если jQuery уже включен в страницу.

Это расширение используется для встраивания jQuery на любую страницу, которую вы хотите. Он позволяет использовать jQuery в оболочке консоли (вы можете вызвать консоль Chrome с помощью «Ctrl + Shift + j»).

Чтобы вставить jQuery в выбранную вкладку, нажмите кнопку расширения.

LINK для расширения: https://chrome.google.com/extensions/detail/gbmifchmngifmadobkcpijhhldeeelkc

  • Обработка двоеточия в идентификаторе элемента с помощью jQuery
  • Разница между функциями $ (window) .load () и $ (document) .ready ()
  • добавить / удалить имя привязки из текущего URL без обновления
  • jQuery: проверьте, существует ли изображение
  • Как скопировать строку таблицы с клоном в jquery и создать новые уникальные идентификаторы для элементов управления
  • инициировать событие при изменении контента
  • jQuery scrollTop не работает в Chrome, но работает в Firefox
  • jQuery получить позицию мыши внутри элемента
  • jQuery .on не работает, но .live делает
  • Использование оператора if для проверки того, является ли div пустым
  • Как остановить ASP.NET от изменения идентификаторов, чтобы использовать jQuery
  • Давайте будем гением компьютера.