¿Cómo insertar dinámicamente una etiqueta <script> a través de jQuery después de cargar la página?


101

Tengo problemas para que esto funcione. Primero intenté configurar mis etiquetas de script como cadenas y luego usar jquery replaceWith () para agregarlas al documento después de cargar la página:

var a = '<script type="text/javascript">some script here</script>';
$('#someelement').replaceWith(a);

Pero obtuve errores literales de cadena en esa var. Luego intenté codificar la cadena como:

var a = '&left;script type="text/javascript"&gt;some script here&lt;\/script&gt;';

pero enviando eso a las replaceWith()salidas solo esa cadena al navegador.

¿Alguien puede decirme cómo haría para agregar dinámicamente una <script>etiqueta en el navegador después de la carga de la página, idealmente a través de jQuery?


¿Puede explicar qué es lo que está tratando de lograr agregando una <script>etiqueta al documento?
Puntiagudo

La respuesta de @ Rocket es la mejor, pero si definitivamente quisiera agregar un script en línea desde una cadena, simplemente lo pasaría a la eval()función. Pero el uso de eval()casi siempre sugiere que existe una mejor manera de hacer lo que está tratando de hacer.
Nick

estamos intentando posponer la carga de anuncios de terceros hasta el final de la página. esos anuncios se llaman a través de 2 etiquetas de script, por lo que quería ejecutar una función después de la carga de la página que los arroje de forma dinámica.
Doug

2
No todos los scripts de terceros están diseñados para ser aplazados. Si el script usa document.writey lo llama después de cargar la página, destruirá la página.
Bobince

1
¿Por qué no importar esas etiquetas en <iframe>elementos? Puede aplazar la configuración de la <iframe>URL hasta que esté listo.
Puntiagudo

Respuestas:


103

Puede poner el script en un archivo separado, luego usarlo $.getScriptpara cargarlo y ejecutarlo.

Ejemplo:

$.getScript("test.js", function(){
    alert("Running test.js");
});

2
gracias, pero ¿eso lo pegará en el DOM? Me doy cuenta de que omití esa información importante, que necesito que la etiqueta de secuencia de comandos se inserte en el DOM, se evalúe, momento en el que devuelve un código de anuncio de terceros para mostrarlo en nuestro sitio en un <div> específico.
Doug

1
$.getScriptsimplemente cargará un archivo .js a través de AJAX y lo ejecutará. No es necesario que el script esté en el DOM para poder acceder a un div en su página.
Rocket Hazmat

6
Pero con $.getScript()el script deberá estar en el mismo dominio o tanto el dominio remoto como el navegador deberán ser compatibles CORS.
hippietrail

14
@hippietrail Eso en realidad no es cierto. Simplemente inserta una etiqueta de script simple, que no requiere CORS o el mismo dominio. Utilizo esto para acortar el código para cargar Google Analytics, por ejemplo, y se carga bien. Detrás de escena, el código jquery real que se ejecuta es bastante similar al fragmento de GA, de hecho.
Chris Moschini

39
Dado que la respuesta de @hippietrail atraerá la mayor atención con sus 4 votos positivos, debe dejarse enfáticamente en claro que es incorrecto. Como destacan los documentos de jQuery en sus $.ajaxnotas: "Las solicitudes de script y JSONP no están sujetas a las mismas restricciones de política de origen". fuente . En otras palabras, $.getScriptpuede extraer archivos .js de otros dominios, no solo del suyo .
Onceavo

64

Intente lo siguiente:

<script type="text/javascript">
// Use any event to append the code
$(document).ready(function() 
{
    var s = document.createElement("script");
    s.type = "text/javascript";
    s.src = "http://scriptlocation/das.js";
    // Use any selector
    $("head").append(s);
});

http://api.jquery.com/append


4
+1 para usar appendpara agregar un script. Agregar hace que incluso el script en línea se evalúe de inmediato (justo lo que necesitaba). Gracias
Gone Coding

1
Termino teniendo muchos problemas en IE8 / 9 con este enfoque. A saber, errores de desbordamiento de pila. Recurrí al método $ .getScript () a continuación para que esto funcione en todos los ámbitos.
zmonteca

1
Sí @jcoffland, esto fue escrito en octubre de 2010 :)
Bassem

Si la página que contiene este código se carga usando AJAX, el navegador lanzará una advertencia "Synchronous XMLHttpRequest en el hilo principal está en desuso debido a sus efectos perjudiciales para la experiencia del usuario final".
Rajshekar Reddy

@Reddy Gran comentario. Esto se publicó en octubre de 2010, estoy seguro de que a estas alturas este método ya no es un enfoque válido / recomendado, los usuarios deben proceder a su propia discreción.
Bassem

34

Esta es la forma correcta de hacerlo con JQuery moderno (2014):

$(function () {
  $('<script>')
    .attr('type', 'text/javascript')
    .text('some script here')
    .appendTo('head');
})

o si realmente desea reemplazar un div, puede hacer:

$(function () {
  $('<script>')
    .attr('type', 'text/javascript')
    .text('some script here')
    .replaceAll('#someelement');
});

3
O en su lugar .text ('algún script aquí') puede escribir .attr ('src', 'path_to_your_js_file')
Serhii Maksymchuk

11

Una forma más sencilla es:

$('head').append('<script type="text/javascript" src="your.js"></script>');

También puede utilizar este formulario para cargar css.


6
Sin </script>embargo, es posible que desee evitar poner la cadena en su fuente, ya que puede causar problemas de análisis: stackoverflow.com/questions/236073/…
iX3

2
escapar del último /hizo el truco para mí:$('head').append('<script src="your.js"><\/script>');
jerik

5

Esta respuesta es técnicamente similar o igual a lo que respondió jcoffland. Acabo de agregar una consulta para detectar si un script ya está presente o no. Necesito esto porque trabajo en un sitio web de intranet con un par de módulos, de los cuales algunos comparten scripts o traen los suyos propios, pero estos scripts no necesitan cargarse cada vez más. Estoy usando este fragmento desde hace más de un año en el entorno de producción, funciona como un encanto. Comentándome a mí mismo: Sí, lo sé, sería más correcto preguntar si existe una función ... :-)

if (!$('head > script[src="js/jquery.searchable.min.js"]').length) {
    $('head').append($('<script />').attr('src','js/jquery.searchable.min.js'));
}

por cierto. Hago lo mismo con las hojas de estilo: if (! $ ('Head> link [href = "widgets / css / widgets.css"]'). Length) {$ ('head'). Append ($ ('<link / > '). attr (' rel ',' stylesheet '). attr (' href ',' widgets / css / widgets.css '));}
ddlab

2

Hay una solución que parece más un truco y estoy de acuerdo en que no es la forma más elegante de hacerlo, pero funciona al 100%:

Digamos que su respuesta AJAX es algo como

<b>some html</b>
<script>alert("and some javscript")

Tenga en cuenta que me he saltado la etiqueta de cierre a propósito. Luego, en el script que carga lo anterior, haga lo siguiente:

$.ajax({
    url: "path/to/return/the-above-js+html.php",
    success: function(newhtml){
        newhtml += "<";
        newhtml += "/script>";
        $("head").append(newhtml);
    }
});

Simplemente no me preguntes por qué :-) Esta es una de esas cosas a las que he llegado como resultado de ensayos desesperados, casi aleatorios y fallidos.

No tengo sugerencias completas sobre cómo funciona, pero curiosamente, NO funcionará si agrega la etiqueta de cierre en una línea.

En momentos como estos, siento que he logrado dividir por cero.


3
No funcionará si la etiqueta de secuencia de comandos de cierre está en una sola pieza, ya que el navegador la ve como la etiqueta de cierre de su secuencia de comandos en lugar de una cadena literal.
Gone Coding

1
<\/script>aunque sería válido
SP

Creo que el punto de @TrueBlueAussie fue en respuesta a tu comentario "No me preguntes por qué ... pero, curiosamente, NO funcionará si agregas la etiqueta de cierre en una línea". Explicó por qué para que cualquier lector que quisiera una mejor respuesta que "No sé" pudiera encontrarla más fácilmente. Véase también: javascript.crockford.com/script.html
iX3

1
@Sathvik tiene razón, según ese enlace. El comentario de Ash parece haber sido una respuesta a uno que fue eliminado.
Arlen Beiler

2

Ejemplo:

var a = '<script type="text/javascript">some script here</script>';
$('#someelement').replaceWith(a);

Deberia de funcionar. Lo intenté; mismo resultado. Pero cuando usé esto:

var length = 1;
var html = "";
for (var i = 0; i < length; i++) {
    html += '<div id="codeSnippet"></div>';
    html += '<script type="text/javascript">';
    html += 'your script here';
    html += '</script>';
}
$('#someElement').replaceWith(a);

Esto funcionó para mí.

Editar: olvidé el #someelement(por cierto, podría querer usarlo #someElementdebido a convenciones)

Lo más importante aquí es + =, por lo que el html se agrega y no se reemplaza.

Deja un comentario si no funcionó. ¡Me gustaría ayudarte!


2

Aquí hay una forma mucho más clara, sin necesidad de jQuery, que agrega un script como último hijo de <body>:

document.body.innerHTML +='<script src="mycdn.js"><\/script>'

Pero si desea agregar y cargar scripts, use el método de Rocket Hazmat .


-4

Si está intentando ejecutar JavaScript generado dinámicamente, sería un poco mejor usar eval. Sin embargo, JavaScript es un lenguaje tan dinámico que realmente no debería necesitarlo.

Si la secuencia de comandos es estática, entonces la getScriptsugerencia de Rocket es el camino a seguir.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.