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

Cadell Christo
sumber
2
setelah berjam-jam berjuang postcribe adalah solusinya! https://github.com/krux/postscribe/
Cadell Christo
Kemungkinan duplikat async memuat javascript dengan document.write
Michał Perłakowski

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);
dmp
sumber
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 );
}
Sirko
sumber
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 );
}
MSS
sumber
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
});
EliSherer
sumber
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(){});
baiklah
sumber
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");
    }
}

jd savaj
sumber
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);
Melayu
sumber
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

Shubham Maurya
sumber
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)
  }
})()
Scott Jungwirth
sumber
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])

Satyam Pathak
sumber
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])

kolorafa
sumber
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.

Moshe Simantov
sumber
0

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

document.body.appendChild(document.createElement('script')).src = 'source.js';
JohnW
sumber