Убедитесь, что внешний Script загружен
Я создаю плагин jquery, и я хочу проверить, загружен ли внешний script. Это для внутреннего веб-приложения, и я могу сохранить имя/местоположение script согласованным (mysscript.js). Это также плагин ajaxy, который можно многократно вызывать на странице.
Если я могу проверить, что script не загружен, я загружу его, используя:
jQuery.getScript()
Как я могу проверить загрузку script, потому что я не хочу, чтобы один и тот же script загружался на страницу более одного раза? Это что-то, что мне не нужно беспокоиться из-за кэширования script?
Обновление:
Возможно, у меня нет контроля над тем, кто использует этот плагин в нашей организации и, возможно, не сможет обеспечить, чтобы script еще не был на странице с определенным идентификатором или без него, но имя script всегда будет в том же место с тем же именем. Я надеюсь, что могу использовать имя script, чтобы убедиться, что оно действительно загружено.
Ответы
Ответ 1
Если script создает любые переменные или функции в глобальном пространстве, вы можете проверить их существование:
Внешний JS (в глобальной области) -
var myCustomFlag = true;
И проверить, выполнено ли это:
if (typeof window.myCustomFlag == 'undefined') {
//the flag was not found, so the code has not run
$.getScript('<external JS>');
}
Update
Вы можете проверить наличие тега <script>
, выбирая все элементы <script>
и проверяя атрибуты src
:
//get the number of `<script>` elements that have the correct `src` attribute
var len = $('script').filter(function () {
return ($(this).attr('src') == '<external JS>');
}).length;
//if there are no scripts that match, the load it
if (len === 0) {
$.getScript('<external JS>');
}
Или вы можете просто испечь эту функциональность .filter()
прямо в селектор:
var len = $('script[src="<external JS>"]').length;
Ответ 2
Ответ @jasper полностью верен, но в современных браузерах стандартное решение Javascript может быть следующим:
function isScriptLoaded(src)
{
return document.querySelector('script[src="' + src + '"]') ? true : false;
}
Ответ 3
Это было очень просто, когда я понял, как это сделать, благодаря всем ответам на то, чтобы привести меня к решению. Мне пришлось отказаться от $.getScript(), чтобы указать источник script... иногда делать вещи вручную лучше.
Решение
//great suggestion @Jasper
var len = $('script[src*="Javascript/MyScript.js"]').length;
if (len === 0) {
alert('script not loaded');
loadScript('Javascript/MyScript.js');
if ($('script[src*="Javascript/MyScript.js"]').length === 0) {
alert('still not loaded');
}
else {
alert('loaded now');
}
}
else {
alert('script loaded');
}
function loadScript(scriptLocationAndName) {
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = scriptLocationAndName;
head.appendChild(script);
}
Ответ 4
Создать тег сценария с определенным идентификатором, а затем проверить, существует ли этот идентификатор?
Кроме того, можно просмотреть теги сценария, проверяя наличие сценария 'src', и убедиться, что они еще не загружены с тем же значением, что и значение, которое вы хотите избежать?
Изменение: после отзыва о том, что пример кода будет полезен:
(function(){
var desiredSource = 'https://sitename.com/js/script.js';
var scripts = document.getElementsByTagName('script');
var alreadyLoaded = false;
if(scripts.length){
for(var scriptIndex in scripts) {
if(!alreadyLoaded && desiredSource === scripts[scriptIndex].src) {
alreadyLoaded = true;
}
}
}
if(!alreadyLoaded){
// Run your code in this block?
}
})();
Как уже упоминалось в комментариях (https://stackoverflow.com/users/1358777/alwin-kesler), это может быть альтернатива (без сравнения):
(function(){
var desiredSource = 'https://sitename.com/js/script.js';
var alreadyLoaded = false;
for(var scriptIndex in document.scripts) {
if(!alreadyLoaded && desiredSource === scripts[scriptIndex].src) {
alreadyLoaded = true;
}
}
if(!alreadyLoaded){
// Run your code in this block?
}
})();
Ответ 5
Этот поток находится в верхней части часто задаваемых вопросов о часах SOQ и имеет огромное количество методов для проверки exisitng script
Лучший способ использования размещенного jQuery Google, но вернуться к моей размещенной библиотеке в Google не удалось
Множество отзывов по различным методам
Ответ 6
Другой способ проверки внешнего script загружен или нет, вы можете использовать функцию datastrong > jquery и сохранить флаг проверки. Пример как:
if(!$("body").data("google-map"))
{
console.log("no js");
$.getScript("https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=initilize",function(){
$("body").data("google-map",true);
},function(){
alert("error while loading script");
});
}
}
else
{
console.log("js already loaded");
}
Ответ 7
Объединение нескольких ответов сверху в простую в использовании функцию
function GetScriptIfNotLoaded(scriptLocationAndName)
{
var len = $('script[src*="' + scriptLocationAndName +'"]').length;
//script already loaded!
if (len > 0)
return;
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = scriptLocationAndName;
head.appendChild(script);
}
Ответ 8
Я думаю, что лучше использовать window.addEventListener('error'), чтобы зафиксировать ошибку загрузки скрипта и попытаться загрузить его снова.
Это полезно, когда мы загружаем скрипты с сервера CDN. Если мы не можем загрузить скрипт из CDN, мы можем загрузить его с нашего сервера.
window.addEventListener('error', function(e) {
if (e.target.nodeName === 'SCRIPT') {
var scriptTag = document.createElement('script');
scriptTag.src = e.target.src.replace('https://static.cdn.com/', '/our-server/static/');
document.head.appendChild(scriptTag);
}
}, true);
Ответ 9
Просто проверьте, доступна ли глобальная переменная, если нет , проверьте еще раз. Чтобы предотвратить превышение максимального стека вызовов, установите для чека тайм-аут 100 мс:
function check_script_loaded(glob_var) {
if(typeof(glob_var) !== 'undefined') {
// do your thing
} else {
setTimeout(function() {
check_script_loaded(glob_var)
}, 100)
}
}
Ответ 10
Слишком мало ответов на этот вопрос, но я считаю, что стоит добавить это решение. Он сочетает в себе несколько разных ответов.
Ключевыми моментами для меня были
- добавьте тег #id, чтобы его было легко найти, а не дублировать
Используйте .onload(), чтобы дождаться окончания загрузки скрипта, прежде чем использовать его
mounted() {
// First check if the script already exists on the dom
// by searching for an id
let id = 'googleMaps'
if(document.getElementById(id) === null) {
let script = document.createElement('script')
script.setAttribute('src', 'https://maps.googleapis.com/maps/api/js?key=' + apiKey)
script.setAttribute('id', id)
document.body.appendChild(script)
// now wait for it to load...
script.onload = () => {
// script has loaded, you can now use it safely
alert('thank me later')
// ... do something with the newly loaded script
}
}
}