Why does jQuery's ajax automatically run scripts?

北战南征 提交于 2021-01-28 19:05:36

问题


I noticed recently that if jQuery ajax is called right after injecting jQuery into an inner iframe, jQuery loses its functions - like jQuery(..).dialog(), .draggable, and any other plugins. If the ajax call is commented out, the jQuery works fine. Is this a known bug, or something I'm doing wrong? This problem can be seen in this file, with jQuery in the same directory:

<html>
<head>
    <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
    <script src="jquery.js"></script>
    <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
</head>
<body>

Try and <button id="btn">load</button>
<iframe width=300 height=300></iframe>

<script>
"use strict";
jQuery('#btn').click(function(){
    var $ = jQuery;
    console.log(typeof jQuery('iframe').dialog);
    var doc = jQuery('iframe')[0].contentDocument;
    function insertscript(src) {
        var newscript = doc.createElement('script');
        newscript.setAttribute('src',src);
        doc.documentElement.appendChild(newscript);
    }
    insertscript('jquery.js');

    //This breaks the jQuery plugins:
    var test = $.get('jquery.js',function(){
        //Now we know jQuery should be in the frame.
    });

    //So does this:
    //jQuery.ajax({url:'http://192.168.1.17/wordpress/wp-includes/js/jquery/jquery.js',cache:true,processData:false});

    console.log(typeof jQuery('iframe').dialog);
    window.setTimeout(function(){
        //jQuery is no longer the original jQuery object. Note the cached reference $().dialog does exist though.
        console.log('after awhile... dialog is ' + typeof jQuery('iframe').dialog);
    },3000)
    //jQuery.ajax({url:jqurl,cache:true,processData:false});
});
</script>
</body></html>

This is a minimal sample of the problem, making sure the iframe has loaded a certain jQuery.js (then ajax should have the cached script) before some other stuff is added to the iframe.

Click load, and after while, console log will show "after awhile... dialog is undefined" - only when ajax was used.

Update: It looks like $.get('jquery.js') actually runs the script. $.get('alert.js') shows an alert, when alert.js has an alert function. (In the case of jQuery, re-defining the global jQuery reference.) Why does jQuery's ajax have this behavior? Does this happen with all ajax implementations?


回答1:


As someone answered earlier (whose answer got deleted?), jQuery ajax automatically chooses what to do depending on what type of content you requested. (An unfortunately under-documented feature). loading an external js will not just return when the browser has fetched the script, it will also run the script.

Whenever you re-include jQuery at a later point, it rewrites the window.jQuery object, therefore removing the jQuery.prototype.dialog, etc.

The Firefox .watch function can be helpful in cases like this, to see where something got redefined. This, for example, would give you a stack trace of anything that redefines jQuery:

window.watch('jQuery',function() { console.trace() } )


来源:https://stackoverflow.com/questions/19872285/why-does-jquerys-ajax-automatically-run-scripts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!