require.config({ paths: { 'jquery': '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery' },shim: { 'jquery.accordion': { deps: ['jquery'] } } });
require(['DisplayAccordion']);
define(['jquery','jquery.accordion'],function($) { $(function() { $('.xyz').accordion(); }); });
注意:jquery.accordion只是一个没有AMD支持的jQuery插件,需要定义全局jQuery变量.
这工作正常,但现在说我在我的页面上放置一个脚本参考到第三方库.例如:
<script src="//example.com/ThirdParty.js"></script>
第三方库加载的是jQuery的自己的版本.现在我得到错误:
Object doesn’t support property or method ‘accordion’.
在遍历代码之后,我发现它按照以下顺序执行:
> ThirdParty.js
> jquery.min.js – 第三方版本
> jquery.min.js – 我的版本
> jquery.accordion.js – 其中$指向我的jQuery引用版本
> DisplayAccordion.js(回调函数) – 其中$指向jQuery的第三方版本
现在我可以看到为什么我得到错误,因为插件附加到一个不同的对象.但是我不知道为什么会这样做.
以下信息将简单解释为什么使用$.noConflict(true)将无法正常工作.
经过一些关于这个问题的研究.我修改了我的配置:
require.config({ paths: { 'jquery': '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery' },map: { '*': { 'jquery': 'jquery-private' },'jquery-private': { 'jquery': 'jquery' } },shim: { 'jquery.accordion': { deps: ['jquery'] } } });
其中jquery-private.js被定义为:
define(['jquery'],function($) { return $.noConflict(true); });
请注意,这是从http://www.requirejs.org/docs/jquery.html#noconflictmap
现在它按照以下顺序执行:
> ThirdParty.js
> jquery.min.js – 第三方版本
> jquery-private.js(回调函数)
> jquery.min.js – 我的版本
> jquery.accordion.js – 其中$未定义
> DisplayAccordion.js(回调函数) – 其中$指向第三方版本
jQuery的
由于$在jquery.accordion.js文件中未定义,因此您可以想像这样不起作用.
进一步调试后,我发现第三方库也调用:
$.noConflict(true);
我想我明白这里发生了什么.当它在第三方库中调用$.noConflict(true)时,它尝试将全局变量$和jQuery设置为以前的版本.但是由于以前没有加载版本,因此设置为undefined.
现在当它调用jquery-private.js并返回$.noConflict(true)时,它将返回已设置为undefined的全局jQuery变量.然而,现在将将全局jQuery变量设置为库的第三方版本.
所以当它加载jquery.accordion $是未定义的.但是当它接下来调用DisplayAccordion.js时,它正在引用第三方版本的jQuery库.
如果有人可以提出修正,我将不胜感激.谢谢
解决方法
一切都需要要求jquery-private而不是jquery – 所以在require()/ define()调用中只提到jquery将在jquery-private本身.
虽然这意味着无法从第三方自动更新的CDN加载它,但它会让其运行在“正确”版本的jQuery.
在此期间(如果您知道哪一个 – GitHub列出了该名称的几个项目),您还可以向GitHub提交一个错误报告/提取请求,使其具有RequireJS能力,然后在更新路径后更改:-)