如何用greasemonkey替换页面的jquery版本?
我试图用更新版本的jquery来测试网站,但我没有开发环境。
答案 0 :(得分:10)
使用源代码控制和书面发布清单构建开发环境将为您带来更多的悲痛(并且是大多数付费工作的必要条件)。
~~~
在现有页面(您无法控制)上替换jQuery版本的最佳方法是:
<script>
节点,其中包含您想要的jQuery版本,在任何后续使用jQuery的脚本之前加载。不幸的是,Greasemonkey不能做#1。它只能在加载之后篡改页面的本机jQuery - 这种方法可能会起作用,但这会降低页面速度并使竞争条件面临风险。
所以,我建议一个双工具解决方案:
确保您的Firefox有the Adblock add-on(这是一个非常好的附加组件,可以使用irregardless)和/或the RequestPolicy add-on。
使用 Adblock 或 RequestPolicy 暂时阻止旧的jQuery。
例如,对于StackOverflow,阻止http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js
。 (请注意, RequestPolicy 允许您将网址限制仅限于特定网站。)
然后使用Greasemonkey在页面开头加载所需版本的jQuery(它可以执行 Adblock 或 RequestPolicy 设置)。< / p>
例如,此脚本将Meta SO的jQuery升级到1.6.2,与第2步中的块一起升级:
// ==UserScript==
// @name _upgrade jQuery
// @include http://meta.stackexchange.com/questions/*
// @run-at document-start
// ==/UserScript==
/*--- Important!
(1) We need another add-on, besides Greasemonkey, to
disable the old, undesired script.
(2) The DOM is not available yet
(@run-at == document-start).
(3) We cannot use a loop to check for the DOM because
loading is halted while the loop runs.
(4) setTimeout() and setInterval() are not fast enough due
to minimum interval clamping. By the time they detect
the DOM, scripts that we need to precede may have
loaded.
(5) Therefor, we use a "set Zero Timeout" function as
explained by David Baron at
http://dbaron.org/log/20100309-faster-timeouts .
(6) By the time FF reports that the `document.head` is
available, several head elements have loaded!
(Is this a bug?)
That means that if any dependent scripts are loaded
before we can inject our jQuery version, then we must
also reload those dependent scripts.
*/
////// setZeroTimeout() implementation: BEGIN
/*--- Only add setZeroTimeout to the window object, and hide
everything else in a closure.
*/
( function () {
var timeouts = [];
var messageName = "zero-timeout-message";
/*--- Like setTimeout, but only takes a function argument.
There's no time argument (always zero) and no arguments.
You have to use a closure.
*/
function setZeroTimeout(fn) {
timeouts.push(fn);
window.postMessage(messageName, "*");
}
function handleMessage(event) {
if (event.source == window && event.data == messageName) {
event.stopPropagation();
if (timeouts.length > 0) {
var fn = timeouts.shift();
fn();
}
}
}
window.addEventListener ("message", handleMessage, true);
// Add the one thing we want added to the window object.
window.setZeroTimeout = setZeroTimeout;
})();
////// setZeroTimeout() implementation: END
/*--- Now wait for the DOM and then add our version of jQuery,
first thing.
*/
function SearchForDOM () {
var targetNode;
if (typeof document.head == "undefined")
targetNode = document.querySelector ("head, body");
else
targetNode = document.head;
if (targetNode) {
var scriptNode = document.createElement ("script");
scriptNode.src = 'http://ajax.googleapis.com/ajax/'
+ 'libs/jquery/1.6.2/jquery.min.js';
targetNode.appendChild (scriptNode);
/*--- By the time FF reports that the head element is
available, a key dependent script has loaded!
So, we reload it here, so that it can run with jQuery
available.
*/
var scriptNode = document.createElement ("script");
scriptNode.src = location.protocol
+ '\/\/' + location.host
+ '/content/js/stub.js?v=49f661361016';
targetNode.appendChild (scriptNode);
}
else
setZeroTimeout (SearchForDOM);
}
SearchForDOM ();
注意:由于JS,GM和Firefox的限制,可能需要重新加载依赖于jQuery的脚本。 (目前这是Meta Stack Overflow的情况。)
答案 1 :(得分:5)
我知道你要求jQuery和Greasemonkey这样做,但让我完全完全不同的选择,Fiddler。
如果您使用新版本的jQuery测试网站并且实际上想要测试任何重大更改等等...您希望测试网站,因为它将是,而基于JavaScript(greasemonkey)的事后替换不是一个准确的模拟。
使用fiddler,您可以替换浏览器请求的文件(无需浏览器知道)。通过这种方式你实际上是在完全测试它,你是直接在页面中删除新版本,没有页面上的JS技巧,可能根本不准确到达那里(处理程序已经连接,加载顺序等。 )
Eric Law(Fiddler的创建者)有一篇关于如何完全的博客文章:
这篇文章的目的是为了更换完整版本的缩小版本(也很方便!)或用于调试的新版本,请务必注意两种用途......它们都是< em>非常可以节省一些调试/测试时间。
答案 2 :(得分:1)
不确定Greasemonkey,但使用Requestly重定向规则是一种简单的方法来修改(URL,图像,脚本)上的任何资源。
注意:
PS:我在Requestly工作。
答案 3 :(得分:0)
对我的案例没有用的东西,似乎适合这个问题,不需要阻挡剂。在GreaseMonkey:
// ==UserScript==
// @name alternative jquery
// @namespace ben@host
// @description intercept
// @include https://somehost.com/*
// @grant GM_getResourceText
// @resource jquery_new jquery_new.js
// @run-at document-start
// @version 1
// ==/UserScript==
var jquery_source = GM_getResourceText( 'jquery_new' );
console.log('jQuery Lenght =',jquery_source.length);
window.addEventListener('beforescriptexecute',
function(e){
if (e.target.src &&
e.target.src.search('/1.12.4/jquery.min.js') >= 0 ) {
console.log('intercepted: '+e.target.src);
e.preventDefault();
e.stopPropagation();
window.eval(jquery_source);
}
});
注意:在检索到原始脚本并准备执行之后,下方 - beforescriptexecute
将触发,因此如果原始外部js文件无法加载,则此方法将无效。