Tambahkan tag skrip secara dinamis dengan src yang mungkin menyertakan document.write


161

Saya ingin secara dinamis memasukkan tag skrip di halaman web namun saya tidak memiliki kontrol src sehingga src = "source.js" mungkin terlihat seperti ini.

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

Sekarang biasanya menempatkan

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

di kepala berfungsi dengan baik tetapi apakah ada cara lain saya dapat menambahkan source.js secara dinamis menggunakan sesuatu seperti innerHTML?

Aku tahu apa yang sudah kucoba


2
setelah berjam-jam berjuang postcribe adalah solusinya! https://github.com/krux/postscribe/
Cadell Christo

Jawaban:


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

Anda dapat menggunakan document.createElement()fungsi seperti ini:

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

Bagaimana Anda membuat async ini?
UKDataGeek

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

s.setAttribute ('src', src); bisa s.src = src (saya pikir?) saya tahu ini bukan pcg
Brandito

68

Ada onloadfungsinya, yang bisa dipanggil ketika skrip berhasil dimuat:

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

1
Belajar sesuatu yang baru. Bagus!
mix3d

16

skrip kecil yang bagus yang saya tulis untuk memuat banyak skrip:

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);
    }
};

pemakaian:

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

2
Maaf ... baru saja menemukan yang lebih baik yang memungkinkan dependensi stackoverflow.com/a/1867135/678780
EliSherer

5

Anda dapat mencoba cuplikan kode berikut.

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

Ini Bekerja Untukku.

Anda bisa memeriksanya.

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

Ketika skrip dimuat secara tidak sinkron, skrip tidak dapat memanggil document.write. Panggilan hanya akan diabaikan dan peringatan akan ditulis ke konsol.

Anda dapat menggunakan kode berikut untuk memuat skrip secara dinamis:

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

Pendekatan ini hanya berfungsi dengan baik ketika sumber Anda milik file yang terpisah.

Tetapi jika Anda memiliki kode sumber sebagai fungsi sebaris yang ingin Anda muat secara dinamis dan ingin menambahkan atribut lain ke tag skrip, misalnya kelas, jenis, dll., Maka potongan berikut akan membantu Anda:

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

2

Nah, ada beberapa cara Anda dapat memasukkan javascript dinamis, saya menggunakan ini untuk banyak proyek.

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);

Anda dapat memanggil membuat fungsi universal yang dapat membantu Anda memuat sebanyak mungkin file javascript. Ada tutorial lengkap tentang ini di sini.

Memasukkan Dynamic Javascript dengan cara yang benar


2
fyi, tautan tidak berfungsi, saya tidak dapat menemukan artikel di tempat lain.
user1063287

1

satu-satunya cara untuk melakukan ini adalah mengganti document.writedengan fungsi Anda sendiri yang akan menambahkan elemen ke bagian bawah halaman Anda. Ini sangat mudah dengan jQuery:

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

Jika Anda memiliki html yang datang ke document.write dalam potongan-potongan seperti contoh pertanyaan Anda perlu buffer htmlToWritesegmen. Mungkin kira-kira seperti ini:

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

1

Saya mencobanya dengan menambahkan setiap skrip secara rekursif

Catatan Jika skrip Anda tergantung satu demi satu, maka posisi harus disinkronkan.

Ketergantungan Besar harus dalam array terakhir sehingga skrip awal dapat menggunakannya

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

Memuat skrip yang bergantung satu sama lain dengan urutan yang benar.

Berdasarkan respons Satyam Pathak , tetapi tetap memperbaiki muatannya. Itu dipicu sebelum skrip benar-benar dimuat.

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

Berikut ini cuplikan yang diperkecil, kode yang sama seperti yang digunakan Google Analytics dan 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");

Ganti https://example.com/foo.jsdengan jalur skrip Anda.


0

Satu kalimat (tidak ada perbedaan mendasar pada jawaban di atas):

document.body.appendChild(document.createElement('script')).src = 'source.js';
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.