簡體   English   中英

如果我動態加載(之前)jQuery,為什么jQuery無法執行加載的腳本?

[英]Why jQuery can't execute a loaded script if I load (before it) jQuery dynamically?

我有一個應用程序,用於檢查當前加載的腳本上是否有jQuery。 如果沒有,我用getScript檢索它並加載一個函數,該函數基本上檢索$.getJSON在json中序列化的html / js,然后執行它:

if (typeof jQuery == 'undefined') {
    if (typeof $ == 'function') {
        thisPageUsingOtherJSLibrary = true;
    }

    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(AbsURL + '/scripts/jquery/jquery-1.9.1.min.js', function () {
        if (typeof jQuery !== 'undefined') {
            if (!thisPageUsingOtherJSLibrary) {
                jQuery(document).ready(function ($) {
                    MyFunction($);
                });
            } else {
                ...
            }
        }
    });
}

function MyFunction($) {
    $.getJSON(AbsURL + "/widget/Init.aspx?" + queryString + "&callback=?", function (html) {
        JsonToHtml(html);
    });

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

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

事實是:如果在加載主頁時使用jQuery,則將執行已加載(反序列化)的腳本,否則將其添加到正文中,但不執行任何操作。

我在這里錯過了哪一步?

問題是已加載腳本的執行。 執行:

<script type="text/javascript">console.log("ciaopollo");</script>

這不是:

<script type="text/javascript">(function (w, d) { var loader = function () { var s = d.createElement("script"), tag = d.getElementsByTagName("script")[0]; s.src = "http://cdn.iubenda.com/iubenda.js"; tag.parentNode.insertBefore(s, tag); }; if (w.addEventListener) { w.addEventListener("load", loader, false); } else if (w.attachEvent) { w.attachEvent("onload", loader); } else { w.onload = loader; } })(window, document);</script>

您可以使用deferred.done()$ get.JSON() 。 由於$get.JSON()是異步並實現了無極接口,讓您得到遞延性質,如.done() .error()等。

因此,請確保您的響應成功,然后再執行下一步,否則請處理錯誤。

來自JQuery文檔的示例:

// Assign handlers immediately after making the request,
// and remember the jqxhr object for this request
var jqxhr = $.getJSON( "example.json", function() {
  console.log( "success" );
})
  .done(function() {
    console.log( "second success" );
  })
  .fail(function() {
    console.log( "error" );
  })
  .always(function() {
    console.log( "complete" );
  });

// Perform other work here ...

// Set another completion function for the request above
jqxhr.complete(function() {
  console.log( "second complete" );
});

另外,如果需要在關鍵渲染路徑之前獲取腳本,則可以通過將其嵌入頭部來加載腳本,某些開發人員使用此策略來防止javascript阻止頁面加載。 以下示例摘錄了獲取Webfonts的代碼:

// this is just another way to create '<script src...'> and
// a method used by placing it in <head></head> so its processed
// before critical render path.
(function() {
    document.getElementsByTagName("html")[0].className += " wf-loading";
    var wf = document.createElement('script');
    wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
    '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
    wf.type = 'text/javascript';
    wf.async = 'true';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(wf, s);
})();

希望這可以幫助。

出於格式化原因,請在此處對以下評論進行回復:請嘗試以下操作:

// optional reference to d, declare var _d;
$.getJSON( file, query , function( d ) { 
  // do nothing or _d = d;
}) 
.done(function( d ) { 
  // call fn(d) 
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM