JS小部件(使用Jquery)与主机页面上的Prototype冲突 [英] JS widget (using Jquery) conflicting with Prototype on host page

查看:107
本文介绍了JS小部件(使用Jquery)与主机页面上的Prototype冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在向其他网站提供Javascript小部件,我在小部件中使用Jquery似乎与主机网站使用Prototype相冲突。



你可以看看这里的冲突:
http://www.phillyrealestateadvocate.idxco.com/idx/8572/results.php?lp=100000&hp= 500000& sqFt = 0& bd = 2& ba = 0& searchSubmit =& city%5B%5D = 131



在右侧页面,单击绿色提出问题按钮 - 它将生成一个弹出窗口,一旦打开弹出窗口,无效的数组长度错误开始滚动到JS控制台(并且不要停止。)弹出窗口然后无法关闭但仍然可以拖延。弹出窗口中的代码/内容位于iframe中,因此它仍然可以正常工作,但弹出窗口不会关闭。



Firebug给出的错误是:
Prototype.js中的数组长度,但是当我为了细节展开它时,它引用了jquery.min.js,所以这让我相信这两个我的小部件代码完全在一个匿名函数中,并使用Alex Marandon所描述的模型加载Jquery:
http://alexmarandon.com/articles/web_widget_jquery/



I我正在使用noConflict调用,但也许它不像我放置的那样工作?



这是我的widget脚本的开头,其中包含对jquery.min.js的引用和jqueryui:

 (function(){

//本地化jQuery变量
var jQuery;

/ ********如果没有,则加载jQuery t present ********* /
if(window.jQuery === undefined || window.jQuery.fn.jquery!=='1.6.2')
{
var script_tag = document.createElement('script');
script_tag.setAttribute(type,text / javascript);
script_tag.setAttribute(src,
http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js);
script_tag.onload = scriptLoadHandler;
script_tag.onreadystatechange = function(){//同样的东西但IE
if(this.readyState =='complete'|| this.readyState =='loaded'){
scriptLoadHandler ();
}
};
//尝试查找头部,否则默认为documentElement
(document.getElementsByTagName(head)[0] || document.documentElement).appendChild(script_tag);
}
其他
{
$ .getScript(https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min。 js,
function()
{
//窗口上的jQuery版本是我们想要使用的那个
jQuery = window.jQuery;
main( );
}
);
}

/ ******** jQuery加载后调用****** /
函数scriptLoadHandler()
{
$ .getScript(https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js,
function()
{
//将$和window.jQuery恢复为之前的值并将
//新jQuery存储在本地jQuery变量中
jQuery = window.jQuery.noConflict(true);
main( );
}
);
}

/ ********我们的主要功能******** /
功能main()
{

//在这里做一堆东西

}

})(); //我们立即调用我们的匿名函数

任何帮助都将不胜感激!



编辑:我现在直接在窗口小部件中安装了Jquery UI,因此我完全取消了getScript调用。不幸的是,这并没有解决冲突。这是新代码:

 (function(){

//本地化jQuery变量
var jQuery,

/ ********如果不存在则加载jQuery ********* /
if(window.jQuery === undefined || window.jQuery.fn.jquery!=='1.6.2')
{
var script_tag = document.createElement('script');
script_tag.setAttribute(type ,text / javascript);
script_tag.setAttribute(src,http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js);
script_tag.onload = scriptLoadHandler;
script_tag.onreadystatechange = function(){//同样的东西但IE
if(this.readyState =='complete'|| this.readyState ==' loading'){
scriptLoadHandler();
}
};
//尝试查找头部,否则默认为documentElement
(document.getElementsByTagName( head)[0] || document.documentElement) .appendChild(script_tag);
}
else
{
jQuery = window.jQuery;
main();
}

/ ******** jQuery加载后调用****** /
函数scriptLoadHandler()
{
jQuery = window.jQuery.noConflict(true);
main();
}

/ ********我们的主要功能******** /
功能main()
{


解决方案

问题是Prototype会覆盖默认的Array.shift方法不完全兼容的方式。 jQuery期望默认行为。



实际上它并没有给jQuery带来问题,当你的页面加载时,你会得到一个类似的错误,这个错误是由加载的curfon-yui.js脚本调用shift引起的那个页面。



让我们在没有加载Prototype的Firebug中试用它:

 > >> []。shift()
undefined

现在在您的页面上:

 >>> [] .shift()
RangeError:无效的数组长度
this [i] = this [i + 1]; this.length - ; return ... ct).join(':') ;})。join(',')+'}>';}}

显然你并不是唯一遇到此问题的人: http:// tommysetiawan.com/post/7887390641/jquery-and-prototype-conflict-array-shift



不幸的是,jQuery的noConflict无法帮助解决这个问题。这个问题似乎在最近的Prototype版本中得到了解决,因此如果您对主机页面有任何控制权,那么更新其Prototype版本可能会有所帮助。它已经导致另一个脚本出错的事实可能是说服该页面的所有者修复它的一个很好的论据。否则,您可能需要修改窗口小部件,以便它不会调用Array.shift,或者您甚至可以尝试以修复它的方式修补Array.shift。


I am providing a Javascript widget to other sites, and my use of Jquery in the widget appears to be conflicting with the host site's use of Prototype.

You can see the conflict in action here: http://www.phillyrealestateadvocate.idxco.com/idx/8572/results.php?lp=100000&hp=500000&sqFt=0&bd=2&ba=0&searchSubmit=&city%5B%5D=131

On the right side of the page, click on the green "Ask a question" button - it will spawn a popup and as soon as you open the popup, "invalid array length" errors start rolling in to the JS console (and don't stop.) The popup is then unable to close but is still draggable. The code/content within the popup is in an iframe, so it still works normally, but the popup just won't close.

The error Firebug gives me is: invalid array length in Prototype.js, but when I expand that for details, it has references to jquery.min.js, so this led me to believe the two are conflicting.

My widget code is entirely in an anonymous function, and loads Jquery using the model described here by Alex Marandon: http://alexmarandon.com/articles/web_widget_jquery/

I am using a noConflict call, but perhaps it's not working the way I placed it?

Here is the beginning of my widget script which contains the references to jquery.min.js and jqueryui:

    (function() {

        // Localize jQuery variable
        var jQuery;

        /******** Load jQuery if not present *********/
        if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.6.2') 
        {
            var script_tag = document.createElement('script');
            script_tag.setAttribute("type","text/javascript");
            script_tag.setAttribute("src",
                "http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js");
            script_tag.onload = scriptLoadHandler;
            script_tag.onreadystatechange = function () { // Same thing but for IE
                if (this.readyState == 'complete' || this.readyState == 'loaded') {
                    scriptLoadHandler();
                }
            };
            // Try to find the head, otherwise default to the documentElement
            (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
        } 
        else 
        {
            $.getScript( "https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js" , 
                function()
                {
                    // The jQuery version on the window is the one we want to use
                    jQuery = window.jQuery;
                    main();
                }
            );
        }

        /******** Called once jQuery has loaded ******/
        function scriptLoadHandler() 
        {
            $.getScript( "https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js" , 
                function()
                {
                    // Restore $ and window.jQuery to their previous values and store the
                    // new jQuery in our local jQuery variable
                    jQuery = window.jQuery.noConflict(true);
                    main(); 
                }
            );
        }

        /******** Our main function ********/
        function main() 
        { 

           // Do a bunch of stuff here

    }

})(); // We call our anonymous function immediately

Any help would be much appreciated!

Edit: I now have Jquery UI directly within the widget, so I eliminated the getScript calls altogether. Unfortunately, this did not fix the conflict. Here is the new code:

(function() {

    // Localize jQuery variable
    var jQuery, 

    /******** Load jQuery if not present *********/
    if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.6.2') 
    {
        var script_tag = document.createElement('script');
        script_tag.setAttribute("type","text/javascript");
        script_tag.setAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js");
        script_tag.onload = scriptLoadHandler;
        script_tag.onreadystatechange = function () { // Same thing but for IE
            if (this.readyState == 'complete' || this.readyState == 'loaded') {
                scriptLoadHandler();
            }
        };
        // Try to find the head, otherwise default to the documentElement
        (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
    } 
    else 
    {
        jQuery = window.jQuery;
        main();
    }

    /******** Called once jQuery has loaded ******/
    function scriptLoadHandler() 
    {
        jQuery = window.jQuery.noConflict(true);
        main(); 
    }

    /******** Our main function ********/
    function main() 
    { 

解决方案

The problem is that Prototype overrides the default Array.shift method in a way that is not fully compatible. jQuery expects the default behaviour.

Actually it's not causing problem only to jQuery, when your page loads, you get a similar error caused by a call to shift in the curfon-yui.js script loaded on that page.

Let's try it in Firebug without Prototype loaded:

  >>> [].shift()
  undefined

Now on your page:

>>> [].shift()
RangeError: invalid array length
this[i]=this[i+1];this.length--;return...ct).join(': ');}).join(', ')+'}>';}} 

Apparently you're not the only one to have this problem: http://tommysetiawan.com/post/7887390641/jquery-and-prototype-conflict-array-shift

jQuery's noConflict won't help with this unfortunately. The issue seems to be solved in more recent versions of Prototype, so if you have any control on the host page it might help to update its version of Prototype. The fact that its already causing errors with another script might be a good argument to convince the owner of that page to fix it. Otherwise you might need to modify your widget so that it doesn't call Array.shift or you could even try to monkey-patch Array.shift in a way that fixes it.

这篇关于JS小部件(使用Jquery)与主机页面上的Prototype冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆