【问题标题】:A script is executed/not executed due to when jQuery is loaded - Why?由于加载 jQuery,脚本被执行/不执行 - 为什么?
【发布时间】:2015-05-06 00:07:15
【问题描述】:

这是我遇到的问题。试试这个code

if (typeof jQuery == 'undefined') {
    function getScript(url, success) {
        var script = document.createElement('script');
        script.src = url;

        var head = document.getElementsByTagName('head')[0];

        done = false;
        script.onload = script.onreadystatechange = function () {
            if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) {
                done = true;
                success();
                script.onload = script.onreadystatechange = null;
                head.removeChild(script);
            };
        };

        head.appendChild(script);
    };

    getScript('http://code.jquery.com/jquery-1.11.2.min.js', function () {
        if (typeof jQuery !== 'undefined') {
            jQuery(document).ready(function ($) {
                MyFunction($);
            });
        }
    });   
} else {
    jQuery(document).ready(function ($) {
        MyFunction($);
    });
}

function MyFunction($) {
    $.getJSON("http://archiesocial.progettiarchimede.it/widget_privacy/test.aspx?asd=1&callback=?", function (d) {
    }).done(function(d) { 
        JsonToHtml(d);
    });
}    

function JsonToHtml(html) {
    var items = [];
    $.each(html, function (key, val) {
        items.push(val);
    });

    $('body').prepend(items.join(''));
} 

您会注意到我的代码检查是否加载了 jQuery。如果没有,它会从外部源加载一个版本;而不是检索 JSON,解析它并“执行它”。

如您所见,加载在正文中的脚本根本没有加载(这是我的问题)。

现在,尝试在 fiddle 中选择一个 jQuery 版本/库(1.8.3 可以)并按下播放:您将看到脚本/按钮渲染:脚本已执行!!!

为什么先加载 jQuery(这里)渲染脚本,然后加载 jQuery 不会执行脚本?你能帮帮我吗?

【问题讨论】:

  • 浏览器控制台中是否有任何错误?
  • @LShetty 复制问题的 jsFiddle 没有错误
  • 看起来问题来自您正在加载的最终脚本 (cdn.iubenda.com/iubenda.js)。但是,该代码已被缩小,因此问题不容易诊断。
  • 听起来缩小的脚本正在使用窗口 onload 事件来设置 iframe,然后因为窗口已经加载而不会触发。编辑:是的,它正在使用w.addEventListener(\"load\", loader, false); 或取决于浏览器w.attachEvent(\"onload\", loader); 但是在调用此脚本时,窗口已经加载
  • 好的。但是为什么之前加载的 jQuery 应该有所作为呢?这是因为,加载外部资源,结束“加载”事件?我该如何解决? @Archer 解决方案似乎有效,但不是那么理想......

标签: javascript jquery


【解决方案1】:

我认为你最好的选择是强制 onload 事件在它已经被触发时被重新触发,因为当你正在加载 jQuery(如果未定义)时,这个事件已经被触发了。这是一种解决方法:

function JsonToHtml(html) {
    var items = [];
    $.each(html, function (key, val) {
        items.push(val);
    });

    $('body').prepend(items.join(''));
    if (document.readyState === 'complete') { // check if document is complete
        var evt = document.createEvent('Event');
        evt.initEvent('load', false, false);
        window.dispatchEvent(evt); // then redispatch onload event
    }
}

-DEMO-

【讨论】:

    【解决方案2】:

    我认为问题在于范围。 MyFunction() 和 JsonToHtml() 函数超出了范围。 (请记住,您正在使用 getJSON 之类的异步函数)也许我的解释是错误的,但代码有效。 :P

    有了这个code,你就没有问题了。

    function _test(){}
    _test.prototype = {
        hasjQuery: function(){
            if(typeof window.jQuery !='undefined' && !_test.prototype.otherLibrary() ) {
                return true;
            }else{
                return false;
            }
        },
        otherLibrary: function(){
            if (typeof document.$ == 'function') {
                return true;
            }else{
                return false;
            }
        },
        inyectjQuery: function(url, success){
            var script = document.createElement('script');
            script.src = url;
            script.id = "delete";
            done = false;
            script.onload = script.onreadystatechange = function() {
                if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) {
                    done = true;
                    success();
                    script.onload = script.onreadystatechange = null
                }
            };
            document.getElementsByTagName('head')[0].appendChild(script)
        },
        myFunction: function(){
            urljQuery = 'http://code.jquery.com/jquery-latest.min.js';
            if(_test.prototype.hasjQuery()){
                jQuery.getJSON("http://archiesocial.progettiarchimede.it/widget_privacy/test.aspx?asd=1&callback=?", 
                    function (d) {
                        _test.prototype.JsonToHtml(d);
                    }).done(function() { 
                        console.log("Success getJSON action");
                    });
            }else{
                _test.prototype.inyectjQuery(urljQuery, function(){
                    if (typeof window.jQuery == 'undefined') {
                        console.log("unable to load jQuery");
                    }else{
                        jQuery.getJSON("http://archiesocial.progettiarchimede.it/widget_privacy/test.aspx?asd=1&callback=?", 
                        function (d) {
                            _test.prototype.JsonToHtml(d);
                        }).done(function() { 
                            console.log("Success getJSON action");
                        });
                    }
                });
            }
        },
        JsonToHtml: function(html){
            var items = [];
            jQuery.each(html, function (key, val) {
                items.push(val);
            });
    
            jQuery('body').prepend(items.join(''));
        }
    }
    test = new _test();
    test.myFunction();
    

    【讨论】:

    • 如果有人认为我的回答是错误的,我想知道为什么。所以,请给我一些反馈。
    • 我没有投反对票,但它们并没有超出范围。它们在上面的代码中具有全局范围,所以它们不能。
    • 严格你是对的。但是当你无法到达函数/变量时,这些不是超出范围吗?
    • 由于它们具有全局范围,因此永远不会定义它们的唯一方法是如果脚本在到达它们之前就崩溃并停止执行。如果发生这种情况,那么这些功能的范围就无关紧要了。
    猜你喜欢
    • 2015-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 2013-09-13
    • 1970-01-01
    相关资源
    最近更新 更多