2015-05-05 1 views
0

У меня есть приложение, проверяющее, есть ли jQuery в текущем загруженном скрипте. Если нет, то я получить его с getScript и загружаю функцию, которая в основном извлекать HTML/JS сериализованная в JSON на $.getJSON, а не выполнять его:Почему jQuery не может выполнить загруженный скрипт, если я загружаю (перед ним) jQuery динамически?

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> 

ответ

1

Вы можете использовать deferred.done() из $get.JSON(). Поскольку $get.JSON() является асинхронным и реализует интерфейс Promise, так что вы получите отложили свойства, такие как .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"); 
}); 

В качестве альтернативы, загрузите скрипт, встраивая его в голову, если вам нужно приобрести его перед critical render path, некоторые разработчики используют эту стратегию, чтобы предотвратить 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) 
}); 
+0

Эмм, я добавил функцию 'JsonToHtml (HTML)' 'внутри .done', но изменить ничего. Он не может отобразить загруженный скрипт :( – markzzz

+0

Я имею в виду, что когда я загружаю скрипт, jQuery (загружается динамически) уже загружен. Я не понимаю, почему он не может «выполнить» сценарий, десериализованный внутри 'JsonToHtml' (вот проблема). – markzzz

+0

@markzzz ответил «UPDATE» выше, не смог отформатировать ответ на этом входе. – daxeh

Смежные вопросы