rob*_*más 10 javascript jquery google-chrome tampermonkey
通常我使用了以下代码片段,这通常有效:
(function () {
function main() {
//...script body...
}
var OGloboCSS = { // var could be named anything, appropriate to the page
addJQuery: function (callback) {
var script = document.createElement("script");
script.setAttribute("src", "https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/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);
}
};
OGloboCSS.addJQuery(main);
})();
Run Code Online (Sandbox Code Playgroud)
但偶尔我会在https://steamcommunity.com上收到类似这样的错误:
拒绝加载脚本' https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js ',因为它违反了以下内容安全策略指令:"script-src'unsafe-eval ''self''unsafe-inline''unsafe-eval'https: //steamcommunity-a.akamaihd.net/ https://api.steampowered.com/ http://www.google-analytics.com https:/ /ssl.google-analytics.com https://www.google.com https://www.gstatic.com https://apis.google.com ".
解决方案基本上是,您必须使用TamperMonkey的@require头指令,如下所示:
// @require https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js
// ==/UserScript==
window.jQ = $;
(function () {
/*this used to be: function main() */
//...same script body, without container function...
})();
Run Code Online (Sandbox Code Playgroud)
这工作得很好,但它不能安全地将jQuery加载到jQ变量,它是clobbers $.这真的是个问题吗?是的,您可以看到在steamcommunity.com的讨论主题中如何分页.
有没有办法@require jQ=然后@grant jQ- 仍然jQ在Tampermonkey脚本和控制台中给我两个,而不会破坏页内变量?
小智 28
除了避免版本冲突和破坏内容页面之外,我还在包含jQuery的默认用户脚本模板中做了一些其他的事情.
下面的模板努力实现以下目标,以便成为将jQuery包含在新脚本中的通用模板,而不管内容页面的任何版本的jQuery自身包含或缺乏内容页面的当前或未来状态.
使用@grant none是关键
//@grant none
Run Code Online (Sandbox Code Playgroud)
@grant none适用于99%的脚本.它允许通过维护UserScript的全局范围(this)轻松访问内容页面的变量,函数和对象,并通过在两个范围内搜索变量,函数标识符来提供对内容页面的全局范围(窗口)的非限定访问. ,窗口顺序.因此,如果您避免复制内容页面中存在的标识符,则可以访问内容页面变量,函数和函数返回值,而无需限定("this."或"window.").您可以在脚本的任何位置执行此操作.
这凸显了OP的原始问题.@grant none提供的便利也是@require指令在加载时覆盖窗口的$和jQuery引用的原因.jQuery库在很长一段时间内都包含了noConflict()函数来处理这个问题.
我们可以立即对上面的答案做一些快速改进,以提高我们的安全性/兼容性/重用性.
window.jQ = $.noConflict(true);
Run Code Online (Sandbox Code Playgroud)
这个代码改为
this.$ = window.jQuery.noConflict(true);
Run Code Online (Sandbox Code Playgroud)
最后一点可能是矫枉过正,但为什么不明确并使用jQuery标识符来进行noConflict调用.虽然在这一点上如果$不是jQuery,当这个调用运行时(@require另一个使用$的库,在此代码运行之前自己使用它等),这将是我们的错误,它可以免费防止以后的调试工作.
虽然我们可以在那里完成并且很开心,但我们还可以进一步确保在各种各样的页面之间的兼容性,以及通过各种各样的内容页面更改.
(function ($, undefined) {
$(function () {
//Your code here;
});
})(window.jQuery.noConflict(true));
Run Code Online (Sandbox Code Playgroud)
虽然仍然无法保证,但这种模式通过将$别名保留在全局范围之外并利用jQuery的DOM Ready事件来确保页面完成,从而为您的功能代码提供了在各种页面生命周期可能性中执行的最佳机会.另外,它还可以确保代码的一致未定义值.
// ==UserScript==
// @name jQuery safe inclusion template
// @description include jQuery and make sure window.$ is the content page's jQuery version, and this.$ is our jQuery version.
// @version 0.0.1
// @author Sonic Beard
// @match http://*.site.com/*
// @require http://cdn.jsdelivr.net/jquery/2.1.3/jquery.min.js
// @grant none
// ==/UserScript==
(function ($, undefined) {
$(function () {
//Your code here;
});
})(window.jQuery.noConflict(true));
Run Code Online (Sandbox Code Playgroud)
TamperMonkey似乎并不具有这样的功能,但替代将立即打电话$.noConflict与removeAll设定参数true.这将导致jQuery重置原始值$并jQuery返回其原始值.
// ==UserScript==
// @name jQuery noConflict test
// @namespace http://example.com/
// @version 0.1
// @description test jQuery noConflict
// @author You
// @match https://steamcommunity.com/
// @require https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js
// @grant none
// ==/UserScript==
window.jQ = $.noConflict(true);
Run Code Online (Sandbox Code Playgroud)
你可以从下面的例子控制台输入看,jQ是一个由加载了jQuery 2.1.3 @require,jQuery是版本的jQuery的页面加载,并且$仍然是原来的原型库对象,通过不jQuery的证明fn财产.
> jQ.fn.jquery
< "2.1.3"
> jQuery.fn.jquery
< "1.11.1"
> $.fn
< undefined
Run Code Online (Sandbox Code Playgroud)