Agregue dinámicamente la etiqueta de script con src que puede incluir document.write


161

Quiero incluir dinámicamente una etiqueta de script en una página web, sin embargo, no tengo control de su src, por lo que src = "source.js" puede verse así.

document.write('<script type="text/javascript">')
document.write('alert("hello world")')
document.write('</script>')
document.write('<p>goodbye world</p>')

Ahora poniendo ordinariamente

<script type="text/javascript" src="source.js"></script> 

en la cabeza funciona bien, pero ¿hay alguna otra manera de agregar source.js dinámicamente usando algo como innerHTML?

jsfiddle de lo que he intentado


2
¡Después de horas de lucha contra la suscripción es la solución! https://github.com/krux/postscribe/
Cadell Christo

Respuestas:


210
var my_awesome_script = document.createElement('script');

my_awesome_script.setAttribute('src','http://example.com/site.js');

document.head.appendChild(my_awesome_script);

94

Puede usar la document.createElement()función de esta manera:

function addScript( src ) {
  var s = document.createElement( 'script' );
  s.setAttribute( 'src', src );
  document.body.appendChild( s );
}

¿Cómo harías esto asíncrono?
UKDataGeek

3
@mobile bloke: s.async = true;
axlotl

s.setAttribute ('src', src); podría ser s.src = src (¿creo?) Sé que esto no es PCG
Brandito

68

Existe la onloadfunción, que podría llamarse cuando el script se ha cargado correctamente:

function addScript( src,callback) {
  var s = document.createElement( 'script' );
  s.setAttribute( 'src', src );
  s.onload=callback;
  document.body.appendChild( s );
}

1
Aprendí algo nuevo. ¡Agradable!
mix3d

16

escribí un pequeño guión para cargar varios guiones:

function scriptLoader(scripts, callback) {

    var count = scripts.length;

    function urlCallback(url) {
        return function () {
            console.log(url + ' was loaded (' + --count + ' more scripts remaining).');
            if (count < 1) {
                callback();
            }
        };
    }

    function loadScript(url) {
        var s = document.createElement('script');
        s.setAttribute('src', url);
        s.onload = urlCallback(url);
        document.head.appendChild(s);
    }

    for (var script of scripts) {
        loadScript(script);
    }
};

uso:

scriptLoader(['a.js','b.js'], function() {
    // use code from a.js or b.js
});

2
Lo siento ... acabo de encontrar uno mejor que permita dependencias stackoverflow.com/a/1867135/678780
EliSherer

5

Puede intentar seguir el fragmento de código.

function addScript(attribute, text, callback) {
    var s = document.createElement('script');
    for (var attr in attribute) {
        s.setAttribute(attr, attribute[attr] ? attribute[attr] : null)
    }
    s.innerHTML = text;
    s.onload = callback;
    document.body.appendChild(s);
}

addScript({
    src: 'https://www.google.com',
    type: 'text/javascript',
    async: null
}, '<div>innerHTML</div>', function(){});

4

Esto es trabajo para mí.

Usted puede comprobarlo.

var script_tag = document.createElement('script');
script_tag.setAttribute('src','https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js');
document.head.appendChild(script_tag);
window.onload = function() {
    if (window.jQuery) {  
        // jQuery is loaded  
        alert("ADD SCRIPT TAG ON HEAD!");
    } else {
        // jQuery is not loaded
        alert("DOESN'T ADD SCRIPT TAG ON HEAD");
    }
}


3

Cuando los scripts se cargan de forma asíncrona, no pueden llamar a document.write. Las llamadas simplemente serán ignoradas y se escribirá una advertencia en la consola.

Puede usar el siguiente código para cargar el script dinámicamente:

var scriptElm = document.createElement('script');
scriptElm.src = 'source.js';
document.body.appendChild(scriptElm);

Este enfoque funciona bien solo cuando su fuente pertenece a un archivo separado.

Pero si tiene el código fuente como funciones en línea que desea cargar dinámicamente y desea agregar otros atributos a la etiqueta del script, por ejemplo, clase, tipo, etc., el siguiente fragmento lo ayudaría:

var scriptElm = document.createElement('script');
scriptElm.setAttribute('class', 'class-name');
var inlineCode = document.createTextNode('alert("hello world")');
scriptElm.appendChild(inlineCode); 
target.appendChild(scriptElm);

2

Bueno, hay varias formas de incluir JavaScript dinámico. Utilizo este para muchos de los proyectos.

var script = document.createElement("script")
script.type = "text/javascript";
//Chrome,Firefox, Opera, Safari 3+
script.onload = function(){
console.log("Script is loaded");
};
script.src = "file1.js";
document.getElementsByTagName("head")[0].appendChild(script);

Puede llamar a crear una función universal que puede ayudarlo a cargar tantos archivos javascript como sea necesario. Hay un tutorial completo sobre esto aquí.

Insertar Javascript dinámico de la manera correcta


2
digo, el enlace no funciona, no pude encontrar el artículo en otro lugar.
user1063287

1

la única forma de hacerlo es reemplazarlo document.writecon su propia función que agregará elementos al final de su página. Es bastante sencillo con jQuery:

document.write = function(htmlToWrite) {
  $(htmlToWrite).appendTo('body');
}

Si tiene html llegando a document.write en fragmentos como el ejemplo de la pregunta, necesitará almacenar en búfer los htmlToWritesegmentos. Tal vez algo como esto:

document.write = (function() {
  var buffer = "";
  var timer;
  return function(htmlPieceToWrite) {
    buffer += htmlPieceToWrite;
    clearTimeout(timer);
    timer = setTimeout(function() {
      $(buffer).appendTo('body');
      buffer = "";
    }, 0)
  }
})()

1

Lo intenté agregando recursivamente cada secuencia de comandos

Nota Si sus scripts dependen uno tras otro, entonces la posición deberá estar sincronizada.

La dependencia mayor debe estar en el último lugar de la matriz para que los scripts iniciales puedan usarla

const scripts = ['https://www.gstatic.com/firebasejs/6.2.0/firebase-storage.js', 'https://www.gstatic.com/firebasejs/6.2.0/firebase-firestore.js', 'https://www.gstatic.com/firebasejs/6.2.0/firebase-app.js']
let count = 0

  
 const recursivelyAddScript = (script, cb) => {
  const el = document.createElement('script')
  el.src = script
  if(count < scripts.length) {
    count ++
    el.onload = recursivelyAddScript(scripts[count])
    document.body.appendChild(el)
  } else {
    console.log('All script loaded')
    return
  }
}
 
  recursivelyAddScript(scripts[count])


1

Carga scripts que dependen unos de otros en el orden correcto.

Basado en la respuesta de Satyam Pathak , pero reparó la carga. Se activó antes de que el script se cargara realmente.

const scripts = ['https://www.gstatic.com/firebasejs/6.2.0/firebase-storage.js', 'https://www.gstatic.com/firebasejs/6.2.0/firebase-firestore.js', 'https://www.gstatic.com/firebasejs/6.2.0/firebase-app.js']
let count = 0

  
 const recursivelyAddScript = (script, cb) => {
  const el = document.createElement('script')
  el.src = script
  if(count < scripts.length) {
    count ++
    el.onload = () => recursivelyAddScript(scripts[count])
    document.body.appendChild(el)
  } else {
    console.log('All script loaded')
    return
  }
}
 
  recursivelyAddScript(scripts[count])


0

Aquí hay un fragmento reducido, el mismo código que utiliza Google Analytics y Facebook Pixel:

!function(e,s,t){(t=e.createElement(s)).async=!0,t.src="https://example.com/foo.js",(e=e.getElementsByTagName(s)[0]).parentNode.insertBefore(t,e)}(document,"script");

Reemplace https://example.com/foo.jscon su ruta de script.


0

Una frase (sin embargo, no hay una diferencia esencial con las respuestas anteriores):

document.body.appendChild(document.createElement('script')).src = 'source.js';
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.