type script para llamar insertar incluir etiqueta escribir ejemplos documentos desde cómo con como combinar javascript element parent

javascript - script - ¿Cómo puedo hacer referencia a la etiqueta de secuencia de comandos que cargó la secuencia de comandos actualmente en ejecución?



script html ejemplos (13)

¿Cómo puedo hacer referencia al elemento de script que cargó el javascript que se está ejecutando actualmente?

Aquí está la situación. Tengo un script "maestro" cargado alto en la página, primero bajo la etiqueta HEAD.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <script type="text/javascript" src="scripts.js"></script>

Hay un script en "scripts.js" que debe ser capaz de realizar la carga a pedido de otros scripts. El método normal no funciona para mí porque necesito agregar nuevos scripts sin hacer referencia a la etiqueta HEAD, porque el elemento HEAD no ha terminado de representarse:

document.getElementsByTagName(''head'')[0].appendChild(v);

Lo que quiero hacer es hacer referencia al elemento de secuencia de comandos que cargó la secuencia de comandos actual para que luego pueda agregar mis nuevas etiquetas de secuencia de comandos cargadas dinámicamente en el DOM después de ello.

<script type="text/javascript" src="scripts.js"></script> loaded by scripts.js--><script type="text/javascript" src="new_script1.js"></script> loaded by scripts.js --><script type="text/javascript" src="new_script2.js"></script>


Cómo obtener el elemento de script actual:

1. Utilice document.currentScript

document.currentScript devolverá el elemento <script> cuyo script se está procesando actualmente.

<script> var me = document.currentScript; </script>

Beneficios

  • Sencillo y explícito. De confianza.
  • No es necesario modificar la etiqueta de script
  • Funciona con scripts asíncronos ( defer y async )
  • Funciona con scripts insertados dinámicamente.

Problemas

  • No funcionará en navegadores antiguos y en IE.

2. Seleccione script por id

Darle al script un atributo de ID le permitirá seleccionarlo fácilmente por ID desde dentro de document.getElementById() .

<script id="myscript"> var me = document.getElementById(''myscript''); </script>

Beneficios

  • Sencillo y explícito. De confianza.
  • Casi universalmente apoyado
  • Funciona con scripts asíncronos ( defer y async )
  • Funciona con scripts insertados dinámicamente.

Problemas

  • Requiere agregar un atributo personalizado a la etiqueta de script
  • id atributo id puede causar un comportamiento extraño para los scripts en algunos navegadores para algunos casos de borde

3. Seleccione el script usando un atributo data-*

Darle al script un atributo data-* te permitirá seleccionarlo fácilmente desde dentro.

<script data-name="myscript"> var me = document.querySelector(''script[data-name="myscript"]''); </script>

Esto tiene pocos beneficios sobre la opción anterior.

Beneficios

  • Sencillo y explícito.
  • Funciona con scripts asíncronos ( defer y async )
  • Funciona con scripts insertados dinámicamente.

Problemas

  • Requiere agregar un atributo personalizado a la etiqueta de script
  • HTML5, y querySelector() no son compatibles en todos los navegadores
  • Menos ampliamente soportado que usar el atributo id
  • Obtendrá alrededor de <script> con casos de borde de id .
  • Puede confundirse si otro elemento tiene el mismo atributo y valor de datos en la página.

4. Seleccione el script por src

En lugar de usar los atributos de datos, puede usar el selector para elegir el script por fuente:

<script src="//example.com/embed.js"></script>

En embed.js:

var me = document.querySelector(''script[src="//example.com/embed.js"]'');

Beneficios

  • De confianza
  • Funciona con scripts asíncronos ( defer y async )
  • Funciona con scripts insertados dinámicamente.
  • No se necesitan atributos personalizados o ID

Problemas

  • No funciona para scripts locales
  • Causará problemas en diferentes entornos, como Desarrollo y Producción.
  • Estático y frágil. Cambiar la ubicación del archivo de script requerirá modificar el script
  • Menos ampliamente soportado que usar el atributo id
  • Causará problemas si carga el mismo script dos veces

5. Recorra todos los scripts para encontrar el que desea.

También podemos recorrer cada elemento del script y marcar cada uno individualmente para seleccionar el que queremos:

<script> var me = null; var scripts = document.getElementsByTagName("script") for (var i = 0; i < scripts.length; ++i) { if( isMe(scripts[i])){ me = scripts[i]; } } </script>

Esto nos permite usar las dos técnicas anteriores en navegadores antiguos que no son compatibles con querySelector() bien con atributos. Por ejemplo:

function isMe(scriptElem){ return scriptElem.getAttribute(''src'') === "//example.com/embed.js"; }

Esto hereda los beneficios y problemas de cualquier enfoque que se tome, pero no depende de querySelector() por lo que funcionará en navegadores más antiguos.

6. Consigue el último script ejecutado.

Dado que los scripts se ejecutan secuencialmente, el último elemento del script será con frecuencia el script actualmente en ejecución:

<script> var scripts = document.getElementsByTagName( ''script'' ); var me = scripts[ scripts.length - 1 ]; </script>

Beneficios

  • Sencillo.
  • Casi universalmente apoyado
  • No se necesitan atributos personalizados o ID

Problemas

  • No funciona con scripts asíncronos ( defer y async )
  • No funciona con scripts insertados dinámicamente.

Aquí hay un poco de un relleno de polietileno que aprovecha el document.CurrentScript si existe y vuelve a encontrar el script por ID.

<script id="uniqueScriptId"> (function () { var thisScript = document.CurrentScript || document.getElementByID(''uniqueScriptId''); // your code referencing thisScript here ()); </script>

Si incluye esto en la parte superior de cada etiqueta de secuencia de comandos, creo que podrá saber constantemente qué etiqueta de secuencia de comandos se está activando, y también podrá hacer referencia a la etiqueta de secuencia de comandos en el contexto de una devolución de llamada asíncrona.

Sin probar, así que deja comentarios para otros si lo intentas.


Considere este algoritmo. Cuando su script se cargue (si hay varios scripts idénticos), busque en document.scripts, encuentre el primer script con el atributo "src" correcto, guárdelo y márquelo como "visitado" con un atributo de datos o un className único.

Cuando se cargue el siguiente script, vuelva a escanear los scripts document, pasando por encima cualquier script que ya esté marcado como visitado. Tome la primera instancia no visitada de ese script.

Esto supone que las secuencias de comandos idénticas probablemente se ejecutarán en el orden en que se cargan, de la cabeza al cuerpo, de arriba a abajo, de síncrono a asíncrono.

(function () { var scripts = document.scripts; // Scan for this data-* attribute var dataAttr = ''data-your-attribute-here''; var i = 0; var script; while (i < scripts.length) { script = scripts[i]; if (/your_script_here/.js/i.test(script.src) && !script.hasAttribute(dataAttr)) { // A good match will break the loop before // script is set to null. break; } // If we exit the loop through a while condition failure, // a check for null will reveal there are no matches. script = null; ++i; } /** * This specific your_script_here.js script tag. * @type {Element|Node} */ var yourScriptVariable = null; // Mark the script an pass it on. if (script) { script.setAttribute(dataAttr, ''''); yourScriptVariable = script; } })();

Esto escaneará a través de todo el script el primer script coincidente que no esté marcado con el atributo especial.

Luego marque ese nodo, si lo encuentra, con un atributo de datos para que las exploraciones posteriores no lo elijan. Esto es similar a los algoritmos de BFS y DFS que atraviesan los gráficos, donde los nodos pueden marcarse como ''visitados'' para evitar la revisión.


Dado que los scripts se ejecutan secuencialmente, la etiqueta de script actualmente ejecutada es siempre la última etiqueta de script en la página hasta entonces. Entonces, para obtener la etiqueta de script, puedes hacer:

var scripts = document.getElementsByTagName( ''script'' ); var thisScriptTag = scripts[ scripts.length - 1 ];


Debe funcionar con la carga de la página y cuando se agrega una etiqueta de script con javascript (por ejemplo, con ajax)

<script id="currentScript"> var $this = document.getElementById("currentScript"); $this.setAttribute("id",""); //... </script>


He encontrado que el siguiente código es el más coherente, eficaz y simple.

var scripts = document.getElementsByTagName(''script''); var thisScript = null; var i = scripts.length; while (i--) { if (scripts[i].src && (scripts[i].src.indexOf(''yourscript.js'') !== -1)) { thisScript = scripts[i]; break; } } console.log(thisScript);


Las secuencias de comandos se ejecutan secuencialmente solo si no tienen un atributo "diferir" o "asíncrono". Saber uno de los posibles atributos ID / SRC / TITLE de la etiqueta de script también podría funcionar en esos casos. Así que las sugerencias de Greg y Justin son correctas.

Ya existe una propuesta para document.currentScript en las listas de WHATWG.

EDIT : Firefox> 4 ya implementa esta propiedad muy útil, pero no está disponible en IE11. Lo verifiqué y solo está disponible en Chrome 29 y Safari 8.

EDITAR : Nadie mencionó la colección "document.scripts", pero creo que la siguiente puede ser una buena alternativa de navegador cruzado para obtener el script actualmente en ejecución:

var me = document.scripts[document.scripts.length -1];


Para obtener la secuencia de comandos, que actualmente carga la secuencia de comandos que puede utilizar

var thisScript = document.currentScript;

Debe mantener una referencia al comienzo de su script, para poder llamar más tarde

var url = thisScript.src


Probablemente, lo más fácil sería darle a su etiqueta de scrip un atributo id .


Si puede asumir el nombre de archivo del script, puede encontrarlo. Hasta ahora solo he probado la siguiente función en Firefox.

function findMe(tag, attr, file) { var tags = document.getElementsByTagName(tag); var r = new RegExp(file + ''$''); for (var i = 0;i < tags.length;i++) { if (r.exec(tags[i][attr])) { return tags[i][attr]; } } }; var element = findMe(''script'', ''src'', ''scripts.js'');


Siga estos sencillos pasos para obtener una referencia al bloque de script en ejecución actual:

  1. Coloque una cadena aleatoria única dentro del bloque de script (debe ser único / diferente en cada bloque de script)
  2. Iterar el resultado de document.getElementsByTagName (''script''), buscando la cadena única de cada uno de sus contenidos (obtenida de la propiedad innerText / textContent).

Ejemplo (ABCDE345678 es el ID único) :

<script type="text/javascript"> var A=document.getElementsByTagName(''script''),i=count(A),thi$; for(;i;thi$=A[--i]) if((thi$.innerText||thi$.textContent).indexOf(''ABCDE345678''))break; // Now thi$ is refer to current script block </script>

Por cierto, para su caso, simplemente puede usar el método antiguo de document.write () para incluir otro script. Como mencionó que el DOM aún no se ha procesado, puede aprovechar el hecho de que el navegador siempre ejecuta el script en secuencia lineal (excepto el diferido que se procesará más adelante), por lo que el resto de su documento aún "no existe". Todo lo que escriba a través de document.write () se colocará justo después de la secuencia de comandos de la persona que llama.

Ejemplo de página HTML original :

<!doctype html> <html><head> <script src="script.js"></script> <script src="otherscript.js"></script> <body>anything</body></html>

Contenido de script.js :

document.write(''<script src="inserted.js"></script>'');

Después de renderizado, la estructura DOM se convertirá en:

HEAD SCRIPT script.js SCRIPT inserted.js SCRIPT otherscript.js BODY


Tengo esto, que funciona en FF3, IE6 y 7. Los métodos en los scripts cargados a pedido no están disponibles hasta que se completa la carga de la página, pero esto sigue siendo muy útil.

//handle on-demand loading of javascripts makescript = function(url){ var v = document.createElement(''script''); v.src=url; v.type=''text/javascript''; //insertAfter. Get last <script> tag in DOM d=document.getElementsByTagName(''script'')[(document.getElementsByTagName(''script'').length-1)]; d.parentNode.insertBefore( v, d.nextSibling ); }


Un enfoque para tratar con scripts asíncronos y diferidos es aprovechar el controlador onload, establecer un controlador onload para todas las etiquetas de script y el primero que se ejecute debe ser suyo.

function getCurrentScript(callback) { if (document.currentScript) { callback(document.currentScript); return; } var scripts = document.scripts; function onLoad() { for (var i = 0; i < scripts.length; ++i) { scripts[i].removeEventListener(''load'', onLoad, false); } callback(event.target); } for (var i = 0; i < scripts.length; ++i) { scripts[i].addEventListener(''load'', onLoad, false); } } getCurrentScript(function(currentScript) { window.console.log(currentScript.src); });