Javascript jQuery无冲突不工作

Javascript jQuery无冲突不工作,javascript,jquery,Javascript,Jquery,我有下面的JavaScript代码,将从客户的网站上引用。它使用jQuery1.5,所以我的问题是,如果客户端已经加载了jQuery实例,该怎么办?还是另一个JavaScript库 我正在使用noConflict()尝试解决这个问题,但它似乎不起作用,我也不知道为什么。谢谢你的帮助 主要的问题是,我得到了一个返回的错误,告诉我jQueryMH是未定义的,但是在我设置keepAlive函数的间隔之前,我已经清楚地定义了它 var head = document.getElementsByTa

我有下面的JavaScript代码,将从客户的网站上引用。它使用jQuery1.5,所以我的问题是,如果客户端已经加载了jQuery实例,该怎么办?还是另一个JavaScript库

我正在使用noConflict()尝试解决这个问题,但它似乎不起作用,我也不知道为什么。谢谢你的帮助

主要的问题是,我得到了一个返回的错误,告诉我jQueryMH是未定义的,但是在我设置keepAlive函数的间隔之前,我已经清楚地定义了它

var head    = document.getElementsByTagName('head')[0];
var script  = document.createElement('script');
script.src  = '//ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js';
script.type = 'text/javascript';
script.onload = script.onreadystatechange = function() {
                                                var jQueryMH = jQuery.noConflict(true);
                                                setInterval(keepAlive(), 5000);
                                            };
head.appendChild(script);
function keepAlive() {
    var mhProtocol      = ((document.location.protocol == "https:") ? "https://" : "http://");
    var randomNumber    = Math.floor(Math.random()*10000);
    var mhVisitorId     = document.cookie.match('mhVisitorId=(.*?)(;|$)');
    var urlParamString  = "";
    if(mhVisitorId) { 
        urlParamString = "&mhVisitorId=" + encodeURIComponent(mhVisitorId[1]); 
    }
    var mhUrl = "www.urlishere.com";
    //var jQueryMH = jQuery.noConflict();
    jQueryMH.ajax({
        url: mhUrl,
        dataType: 'jsonp'
    });
}
除此之外,我还尝试在函数本身中设置noConflict(),这可以工作,并允许我引用jQueryMH,但是我们有以下问题,可能是因为每次函数运行时(每5秒)都会设置noConflict


我设置的外部包含这个JS脚本的测试页面已经加载了jQuery1.8,然后加载了上面的脚本。因此,由于我的noConflict,我希望jQueryMH.fn.jquery返回1.5.0,jquery.fn.jquery返回1.8;但是,它们都返回1.5.0,这意味着我的noConflict不起作用,因为jQuery不会停留在已加载到客户端网站的版本1.8库中。

在加载第二个版本之前,实际上需要
noConflict
第一个版本,否则第二个版本只会覆盖第一个版本

除此之外,导致未定义变量问题的原因是在函数中调用
.noconflict
,并将jQuery分配给仅在该函数范围内的备用变量

var head    = document.getElementsByTagName('head')[0];
var script  = document.createElement('script');
script.src  = '//ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js';
script.type = 'text/javascript';
script.onload = script.onreadystatechange = function() {
                                                var jQueryMH = jQuery.noConflict(true);
                                                setInterval(keepAlive(), 5000);
                                            };
head.appendChild(script);
function keepAlive() {
    var mhProtocol      = ((document.location.protocol == "https:") ? "https://" : "http://");
    var randomNumber    = Math.floor(Math.random()*10000);
    var mhVisitorId     = document.cookie.match('mhVisitorId=(.*?)(;|$)');
    var urlParamString  = "";
    if(mhVisitorId) { 
        urlParamString = "&mhVisitorId=" + encodeURIComponent(mhVisitorId[1]); 
    }
    var mhUrl = "www.urlishere.com";
    //var jQueryMH = jQuery.noConflict();
    jQueryMH.ajax({
        url: mhUrl,
        dataType: 'jsonp'
    });
}
我认为您首先需要做:

var origjQuery = jQuery.noconflict();
然后像上面那样加载新的jQuery,然后
noconflict

var jQueryMH = jQuery.noconflict();
然后恢复原始jQuery:

var jQuery = origjQuery.noconflict();

在全局范围内执行上述所有操作。

在任何其他主机上注入脚本时,我实际上遇到了这个问题

正如Alnitak所述,
noConflict
在您首先加载jQuery,然后覆盖
$
变量时起作用,而不是相反

我设法构建的变通方法使用ECMAScript 5中的和方法

问题是将要在现有站点上覆盖的变量(如
$
)复制到最终将冻结的对象中。
通过在重写变量之前冻结该对象(在加载jQuery之前),您可以确保原始变量的副本(在您的情况下,
$
)将存储在您的对象中,并且它们不能被任何其他脚本以任何方式更改。
加载所需的LIB后,只需将已冻结的对象属性复制回全局对象中,主机环境保持不变。
下面是一个示例代码,让事情更清楚:

var aux = {'jQuery' : window.jQuery};
if(Object.freeze)
    // prevent anyone from deleting any of the `aux` props
    Object.freeze(aux);
if(Object.seal)
    // prevent anyone from altering the initial jQuery
    // this is necessary because `aux.jQuery` is a copy by reference of the
    // window.jQuery, thus any modification in the global jQuery object
    // would be reflected in our jQuery copy
    Object.seal(aux.jQuery);

var head    = document.getElementsByTagName('head')[0];
var script  = document.createElement('script');
script.src  = '//ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js';
script.type = 'text/javascript';
script.onload = script.onreadystatechange = function() {
    var jQueryMH = jQuery.noConflict(true);
    // restore the initial jquery
    window.jQuery = aux.jQuery;
    alert(jQuery === jQueryMH);
};
当然,您可以扩展该功能并将其用于您使用的任何其他LIB:

var __globalLibs = {},
    libsThatYouWantToPreserve = '$ jQuery otherLib'.split(' '),
    key;

for(var i=0,l=libsThatYouWantToPreserve.length;i<l;i++)
    {
        key = libsThatYouWantToPreserve[i];
        // copy the contents of the global variable into your object
        __globalLibs[key] = window[key];
        if(Object.seal)
            Object.seal(__globalLibs[key]);
    }

if(Object.freeze)
    Object.freeze(__globalLibs);

// load jquery and all the other libs

// make copies of your update libs

var jQueryMH = jQuery;

// and then restore the initial variables to the global context
 for(var i=0,l=libsThatYouWantToPreserve.length;i<l;i++)
    {
        key = libsThatYouWantToPreserve[i];
        // copy the contents of the global variable into your object
        window[key] = __globalLibs[key];
    }

// after that, you can just delete your object
delete window.__globalLibs; 
var\uuu globalLibs={},
libsThatYouWantToPreserve='$jQuery otherLib'.split(''),
钥匙

对于(var i=0,l=libsthatwainttopreserve.length;i我构建了一个jQuery的自定义构建,修改了将jQuery分配给全局变量的代码行

具体而言,我将该行代码转换为:

window.jQuery = window.$ = jQuery;


这样,即使页面中包含jQuery脚本,我也可以毫无问题地注入我的自定义jQuery版本,无需密封/冻结实际的全局jQuery,也无需使用.noConflict(),这两种解决方案都会导致上述问题。

setInterval(keepAlive(),5000);
->
setInterval(function(){keepAlive(jQueryMH);},5000);
函数keepAlive(){
->
函数keepAlive(jQueryMH){
我不知道客户端是否会加载jQuery库,显然我可以检查jQuery变量的类型,但我也不能修改它们的设置,例如,如果他们的页面中包含1.8,并且他们有一些仅1.8.x的插件,我需要确保他们网站上没有任何内容被修改。在我包含externa之后将JS文件加载到我的测试页面(已经加载了1.8),然后输出jQuery/$it show 1.8的版本,在我的外部JS脚本中,我输出jQueryMH的版本,它显示1.5,这对我来说似乎很好。如果页面中已经存在的jQuery执行了某些操作(比如jQuery插件),该怎么办在冻结/封存和新jQuery加载结束之间?如果执行的jQuery插件管理其状态,将无法修改此状态,因此将创建不一致的状态/情况,不是吗?