Estoy creando un complemento jquery y quiero verificar que se cargue un script externo. Esto es para una aplicación web interna y puedo mantener el nombre / ubicación del script consistente (mysscript.js). Este también es un complemento ajaxy al que se puede llamar muchas veces en la página.
Si puedo verificar que el script no está cargado, lo cargaré usando:
jQuery.getScript()
¿Cómo puedo verificar que el script esté cargado porque no quiero que el mismo script se cargue en la página más de una vez? ¿Es esto algo de lo que no debería preocuparme debido al almacenamiento en caché del script?
Actualización: es posible que no tenga control sobre quién usa este complemento en nuestra organización y es posible que no pueda hacer cumplir que el script no esté ya en la página con o sin una ID específica, pero el nombre del script siempre estará en el mismo lugar con el mismo nombre. Espero poder usar el nombre del script para verificar que esté realmente cargado.
fuente
Respuestas:
Si el script crea variables o funciones en el espacio global, puede verificar su existencia:
JS externo (en alcance global) -
var myCustomFlag = true;
Y para verificar si esto se ha ejecutado:
if (typeof window.myCustomFlag == 'undefined') { //the flag was not found, so the code has not run $.getScript('<external JS>'); }
Actualizar
Puede verificar la existencia de la
<script>
etiqueta en cuestión seleccionando todos los<script>
elementos y verificando sussrc
atributos://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>'); }
O simplemente puede hornear esta
.filter()
funcionalidad directamente en el selector:var len = $('script[src="<external JS>"]').length;
fuente
$.getScript()
que pueda establecer un indicador global que puede ser verificado:$.getScript('<external JS>, function () { window.myCustomFlag = true; }')
. Luego, puede verificar la existencia del<script>
elemento específico o lamyCustomFlag
variable.La respuesta de @ jasper es totalmente correcta, pero con los navegadores modernos, una solución estándar de Javascript podría ser:
function isScriptLoaded(src) { return document.querySelector('script[src="' + src + '"]') ? true : false; }
fuente
Boolean
lugar del operador condicional, si lo deseareturn document.querySelector('script[src="' + src + '"]');
document.querySelector('head').append(script_el); console.log(isScriptLoaded(script_el.src)
devuelvetrue
pero el script aún no se ejecutó.Pocas respuestas en este caso, pero creo que vale la pena agregar esta solución. Combina algunas respuestas diferentes.
Los puntos clave para mí fueron
Use .onload () para esperar hasta que el script haya terminado de cargarse antes de usarlo
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 } } }
fuente
script.onload
es la respuesta correcta aquí. ¡Gracias por compartir!Esto fue muy simple ahora que me doy cuenta de cómo hacerlo, gracias a todas las respuestas por llevarme a la solución. Tuve que abandonar $ .getScript () para especificar la fuente del script ... a veces es mejor hacer las cosas manualmente.
Solución
//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); }
fuente
¿Cree la etiqueta de secuencia de comandos con una identificación específica y luego verifique si esa identificación existe?
Alternativamente, recorra las etiquetas de script para verificar el script 'src' y asegúrese de que no estén cargadas con el mismo valor que el que desea evitar
Editar: siguiendo los comentarios de que un ejemplo de código sería útil:
(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? } })();
Como se menciona en los comentarios ( https://stackoverflow.com/users/1358777/alwin-kesler ), esta puede ser una alternativa (no comparada):
(function(){ var desiredSource = 'https://sitename.com/js/script.js'; var scripts = document.getElementsByTagName('script'); 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? } })();
fuente
document.getElementsByTagName('script')
pero no lo he probadoOtra forma de verificar que un script externo esté cargado o no, puede usar la función de datos de jquery y almacenar una bandera de validación. Ejemplo como:
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"); }
fuente
Fusionar varias respuestas de arriba en una función fácil de usar
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); }
fuente
Creo que es mejor usar window.addEventListener ('error') para capturar el error de carga del script e intentar cargarlo nuevamente. Es útil cuando cargamos scripts desde un servidor CDN. Si no podemos cargar el script desde la CDN, podemos cargarlo desde nuestro servidor.
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);
fuente
Simplemente verifique si la variable global está disponible , si no , vuelva a verificar . Para evitar que se exceda la pila de llamadas máxima, establezca un tiempo de espera de 100 ms en la verificación:
function check_script_loaded(glob_var) { if(typeof(glob_var) !== 'undefined') { // do your thing } else { setTimeout(function() { check_script_loaded(glob_var) }, 100) } }
fuente