我已经开始开发浏览器扩展。我注意到一个常见的概念是扩展可以将 JS 代码注入当前浏览器选项卡。
我对这不会经常引起问题感到有些困惑。
我的意思是,如果我在已经包含 JQuery 版本 y 的页面中注入版本 x 的 JQuery(通过我的浏览器扩展程序),事情怎么可能仍然有效?功能不会有冲突$()
吗?
事情怎么可能这么顺利?开发人员是否应该采用任何特定技术来确保不会发生此类冲突,或者浏览器会处理所有事情?
我已经开始开发浏览器扩展。我注意到一个常见的概念是扩展可以将 JS 代码注入当前浏览器选项卡。
我对这不会经常引起问题感到有些困惑。
我的意思是,如果我在已经包含 JQuery 版本 y 的页面中注入版本 x 的 JQuery(通过我的浏览器扩展程序),事情怎么可能仍然有效?功能不会有冲突$()
吗?
事情怎么可能这么顺利?开发人员是否应该采用任何特定技术来确保不会发生此类冲突,或者浏览器会处理所有事情?
虽然noConflict()
可能大部分时间都适用于 jQuery,但它对于扩展仍然不是一个好主意,并且不适用于大多数其他库或实用程序。
明智的做法是根本不注入代码(有一个例外1)。该扩展可以包含您需要的任何库,这样做有很多好处:
不存在与页面的 javascript 冲突的可能性。
对页面的 JS 没有依赖,它会在没有通知的情况下发生变化,您的扩展将不那么频繁地中断。
当您注入一个库时,它必须从某个外部服务器中获取。这会减慢您的扩展程序并使其容易受到您无法控制的崩溃的影响。
当您在扩展中包含该库时,它是:(a) 始终存在,(b) 始终是已知良好的版本,以及 (c) 几乎立即从本地计算机加载,而不是从某个遥远的服务器加载。
即使页面的 javascript 被禁用,您的扩展程序也可以运行。
您的扩展可以同时利用库和扩展 API。
使用扩展很容易合并像 jQuery 这样的库。例如,使用 Chrome:
将库添加到manifest.json
文件中。
一个包含 jQuery 的简单清单可以是:
{
"content_scripts": [ {
"exclude_globs": [ ],
"include_globs": [ "*" ],
"js": [ "jquery.min.js", "myJS.js" ],
"matches": [ "http://stackoverflow.com/*"
]
} ],
"description": "Hello world with jQuery",
"name": "Hello world with jQuery",
"version": "1"
}
Firefox 和其他浏览器的机制类似。
1一个例外?对于扩展,当且仅当满足所有这些条件时才注入代码:
这个问题的常见解决方案是使用 jQuery.noConflict() 将 jQuery 别名为不同的变量,确保它不会与页面的$
.
jQuery 有一个noConflict()
函数可以用来将 jQuery 与使用$
命名空间的其他任何东西(例如不同的 jQuery 实例)隔离开来。
避免前向命名空间污染的更通用方法是考虑在闭包中执行 JavaScript。
(function () {
// Your Code Here
})();
这将防止闭包范围内的任何内容在您自己的代码之外可用。