Tự động thêm thẻ script với src có thể bao gồm document.write


160

Tôi muốn tự động bao gồm thẻ script trong một trang web tuy nhiên tôi không kiểm soát được src nên src = "source.js" có thể trông như thế này.

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

Bây giờ thường đặt

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

trong đầu hoạt động tốt nhưng có cách nào khác để tôi có thể thêm source.js một cách linh hoạt bằng cách sử dụng một cái gì đó như InternalHTML không?

jsfiddle về những gì tôi đã cố gắng


2
sau nhiều giờ vật lộn đăng ký là giải pháp! https://github.com/krux/postscribe/
Cadell Christo

Câu trả lời:


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

Bạn có thể sử dụng document.createElement()chức năng như thế này:

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

Làm thế nào bạn sẽ làm cho async này?
UKDataGeek

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

s.setAttribution ('src', src); có thể là s.src = src (tôi nghĩ vậy?) tôi biết đây không phải là
pcg

67

onloadchức năng, có thể được gọi khi tập lệnh được tải thành công:

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

Đã học được điều gì đó mới. Đẹp!
mix3d

16

một kịch bản nhỏ đẹp tôi đã viết để tải nhiều tập lệnh:

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

sử dụng:

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

2
Xin lỗi ... chỉ tìm thấy một cái tốt hơn cho phép phụ thuộc stackoverflow.com/a/1867135/678780
EliSherer

5

Bạn có thể thử đoạn mã sau.

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

Đây là công việc cho tôi.

Bạn có thể kiểm tra nó.

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

Khi các tập lệnh được tải không đồng bộ, chúng không thể gọi document.write. Các cuộc gọi sẽ đơn giản được bỏ qua và một cảnh báo sẽ được ghi vào bàn điều khiển.

Bạn có thể sử dụng mã sau đây để tải tập lệnh một cách linh hoạt:

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

Cách tiếp cận này chỉ hoạt động tốt khi nguồn của bạn thuộc về một tệp riêng biệt.

Nhưng nếu bạn có mã nguồn là các hàm nội tuyến mà bạn muốn tải động và muốn thêm các thuộc tính khác vào thẻ script, ví dụ: lớp, loại, v.v., thì đoạn mã sau sẽ giúp bạn:

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

2

Vâng, có nhiều cách bạn có thể bao gồm javascript động, tôi sử dụng cách này cho nhiều dự án.

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

Bạn có thể gọi tạo một chức năng phổ quát có thể giúp bạn tải bao nhiêu tệp javascript nếu cần. Có một hướng dẫn đầy đủ về điều này ở đây.

Chèn Javascript động đúng cách


2
fyi, liên kết không hoạt động, tôi không thể tìm thấy bài viết ở nơi khác.
dùng1063287

1

cách duy nhất để làm điều này là thay thế document.writebằng chức năng của chính bạn sẽ nối các phần tử vào cuối trang. Nó khá dễ dàng với jQuery:

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

Nếu bạn có html đến với document.write trong các đoạn như ví dụ câu hỏi, bạn sẽ cần phải đệm các htmlToWritephân đoạn. Có lẽ một cái gì đó như thế này:

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

1

Tôi đã thử nó bằng cách nối thêm từng tập lệnh

Ghi chú Nếu tập lệnh của bạn phụ thuộc lần lượt từng vị trí, thì vị trí sẽ cần phải được đồng bộ hóa.

Sự phụ thuộc chính phải ở cuối cùng trong mảng để các tập lệnh ban đầu có thể sử dụng nó

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

Tải các tập lệnh phụ thuộc vào nhau với thứ tự đúng.

Dựa trên phản hồi Satyam Pathak , nhưng đã sửa lỗi tải. Nó được kích hoạt trước khi tập lệnh thực sự được tải.

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

Dưới đây là đoạn trích được rút gọn, cùng mã với Google Analytics và Facebook Pixel sử dụng:

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

Thay thế https://example.com/foo.jsbằng đường dẫn kịch bản của bạn.


0

Một lớp lót (không có sự khác biệt cần thiết cho các câu trả lời ở trên):

document.body.appendChild(document.createElement('script')).src = 'source.js';
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.