Javascript 在小部件中透明地加载和使用jQuery,且没有冲突
前提:我需要制作一个透明可重用的小部件,它使用jQuery并可以在任何页面上工作(即使页面加载并使用自己版本的jQuery);小部件将通过主机页面上的单个Javascript 在小部件中透明地加载和使用jQuery,且没有冲突,javascript,jquery,ecmascript-6,Javascript,Jquery,Ecmascript 6,前提:我需要制作一个透明可重用的小部件,它使用jQuery并可以在任何页面上工作(即使页面加载并使用自己版本的jQuery);小部件将通过主机页面上的单个标记加载 我知道noConflict()建议的解决方案,例如 我有两个顾虑: 由于小部件本身是通过JS标记加载的,因此它将插入文档以加载jQuery库的任何标记都将异步加载(AFAIK,即使使用document.write());因此,两步noConflict()解析充其量是不可靠的 小部件还需要加载各种jQuery插件;一旦jQuery能够在
标记加载
我知道noConflict()建议的解决方案,例如
我有两个顾虑:
标记都将异步加载(AFAIK,即使使用document.write()
);因此,两步noConflict()
解析充其量是不可靠的jQuery\u小部件
global,我如何使这些插件绑定到jQuery\u小部件
,而不是jQuery
想到的另一个肮脏的解决方案是在iframe中加载所有内容,并使用
iframe.contentWindow.$
来操作主机窗口;我不知道jQuery跨帧的可靠性有多高,但我从未尝试过类似的方法。您至少有两种选择:
script
标记,触发对浏览器无法预测、因此无法预取的每个资源(jQuery、插件、您的代码)的HTTP请求。这对性能没有好处
标记加载
这一部分对这项工作至关重要。如果有人使用延迟
或异步
,它将不起作用。由于加载时间的影响,我建议您的小部件的用户将脚本标记放在文档的末尾,就在关闭
标记之前
使用document.write
,让您的widget.js
按以下顺序输出脚本:
$
和jQuery
全局标识符jQuery
global向jQuery注册(如果编写正确的话)$
和jQuery
全局变量返回到步骤1之前的状态,并在该作用域函数中为您提供一个$
本地变量,以便在代码中使用但是,您可能可以避免这种情况。绑定器早在ES2015之前就存在了,但是即使你找不到,你也可以自己做:按照上面给出的顺序,用
连接你的各种脚本代码>在它们之间,放入一个widget.js
文件,并通过任何合适的迷你程序运行它。这将使页面上任何预加载的jQuery不受上述原因的影响,而只需要一个HTTP请求。它还允许您的用户使用async
或defer
,因为您的脚本不必使用document.write。
您至少有两个选项:
按照您所描述的操作,这将涉及到您的小部件向目标页面输出script
标记,触发对浏览器无法预测、因此无法预取的每个资源(jQuery、插件、您的代码)的HTTP请求。这对性能没有好处
把代码打包
让我们把它们整理一下
做你想做的事
…小部件将通过主机页面上的单个
标记加载
这一部分对这项工作至关重要。如果有人使用延迟
或异步
,它将不起作用。由于加载时间的影响,我建议您的小部件的用户将脚本标记放在文档的末尾,就在关闭
标记之前
使用document.write
,让您的widget.js
按以下顺序输出脚本:
您的jQuery副本。这将临时接管$
和jQuery
全局标识符
您需要的所有jQuery插件。它们将通过jQuery
global向jQuery注册(如果编写正确的话)
包含主代码的脚本,其开头为(在作用域函数内):
…这将使$
和jQuery
全局变量返回到步骤1之前的状态,并在该作用域函数中为您提供一个$
本地变量,以便在代码中使用
捆绑代码
但是,您可能可以避免这种情况。绑定器早在ES2015之前就存在了,但是即使你找不到,你也可以自己做:按照上面给出的顺序,用连接你的各种脚本代码>在它们之间,放入一个widget.js
文件,并通过任何合适的迷你程序运行它。这将使页面上任何预加载的jQuery不受上述原因的影响,而只需要一个HTTP请求。它还允许您的用户使用异步
或延迟
,因为您的脚本不必使用文档。写入。
谢谢,您是否肯定文档。写入同步加载
标记?我记得我和t的成绩参差不齐
(function() {
const $ = jQuery.noConflict(true);
// ...the main body of your code here...
})();