jQuery doesn't work in Greasemonkey at all. Is there other way to use jQuery in Greasemonkey? For all the people who have the same problem, you must upload the file to greasespot then install it from there.
Greasemonkey user scripts are written in JavaScript and manipulate the contents of a web page using the Document Object Model interface.
From "User Script Tip: Using jQuery - Erik Vold's Blog"
// ==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);
I have written a few functions based on the Erik Vold's script to help run me run functions, code and other scripts in a document. You can use them to load jQuery into the page and then run code under the global window
scope.
// ==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");
});
You can click here to install it, if you trust that I'm not trying to trick you into installing something malicious and that nobody has edited my post to point to something else. Reload the page and you should see a border around my post.
load(url, onLoad, onError)
Loads the script at url
into the document. Optionally, callbacks may be provided for onLoad
and onError
.
execute(functionOrCode)
Inserts a function or string of code into the document and executes it. The functions are converted to source code before being inserted, so they lose their current scope/closures and are run underneath the global window
scope.
loadAndExecute(url, functionOrCode)
A shortcut; this loads a script from url
, then inserts and executes functionOrCode
if successful.
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); });
}
Use jQuery without fear of conflicts, by calling jQuery.noConflict(true)
. Like so:
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);
}
But, For cross-browser scripts, why not take advantage of a nice, fast, local copy of jQuery, when you can?
The following works as a Chrome userscript and a Greasemonkey script, and it uses the nice local @require
copy of jQuery, if the platform supports it.
// ==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);
}
If the page already has jQuery, then just follow this template:
// ==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);
The simple way is using required
keyword:
// @require http://code.jquery.com/jquery-latest.js
There's a really easy way to get around including a full copy of jQuery for Chrome scripts when those scripts don't actually use any privileged features (GM_* functions, etc)...
Simply insert the script itself into the page DOM and execute! The best part is that this technique works just as well on Firefox+Greasemonkey, so you can use the same script for both:
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 stolen from Shog9 on meta.stackoverflow since he didn't move it here, and I have to delete the meta post..)
Also, you could pack your script with jQuery to Chrome extension. See Google Chrome's Content Scripts.
Chrome extensions, unlike Greasemonkey scripts, can auto-update itself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With