Javascript 使用src动态添加脚本标记,该标记可能包括document.write

Javascript 使用src动态添加脚本标记,该标记可能包括document.write,javascript,src,document.write,Javascript,Src,Document.write,我想在网页中动态地包含一个脚本标记,但是我无法控制它的src,所以src=“source.js”可能是这样的 document.write('<script type="text/javascript">') document.write('alert("hello world")') document.write('</script>') document.write('<p>goodbye world</p>') document.write

我想在网页中动态地包含一个脚本标记,但是我无法控制它的src,所以src=“source.js”可能是这样的

document.write('<script type="text/javascript">')
document.write('alert("hello world")')
document.write('</script>')
document.write('<p>goodbye world</p>')
document.write(“”)
document.write('alert(“hello world”)'))
文件。写入(“”)
文档。编写(“再见世界”

”)
现在

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

在head中可以很好地工作,但是有没有其他方法可以使用innerHTML之类的东西动态添加source.js

您可以使用如下功能:

function addScript( src ) {
  var s = document.createElement( 'script' );
  s.setAttribute( 'src', src );
  document.body.appendChild( s );
}
document.write = (function() {
  var buffer = "";
  var timer;
  return function(htmlPieceToWrite) {
    buffer += htmlPieceToWrite;
    clearTimeout(timer);
    timer = setTimeout(function() {
      $(buffer).appendTo('body');
      buffer = "";
    }, 0)
  }
})()

onload
函数,当脚本成功加载时可以调用该函数:

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

我编写了一个很好的小脚本来加载多个脚本:

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

唯一的方法是替换
文档。使用自己的函数编写
,该函数会将元素附加到页面底部。jQuery非常简单:

document.write = function(htmlToWrite) {
  $(htmlToWrite).appendTo('body');
}
如果有html进入document.write,就像问题示例那样,需要缓冲
htmlToWrite
段。也许是这样的:

function addScript( src ) {
  var s = document.createElement( 'script' );
  s.setAttribute( 'src', src );
  document.body.appendChild( s );
}
document.write = (function() {
  var buffer = "";
  var timer;
  return function(htmlPieceToWrite) {
    buffer += htmlPieceToWrite;
    clearTimeout(timer);
    timer = setTimeout(function() {
      $(buffer).appendTo('body');
      buffer = "";
    }, 0)
  }
})()

您可以尝试以下代码段

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(){});
函数addScript(属性、文本、回调){
var s=document.createElement('script');
for(属性中的var attr){
s、 setAttribute(属性,属性[attr]?属性[attr]:空)
}
s、 innerHTML=文本;
s、 onload=回调;
文件。正文。附录子项;
}
添加脚本({
src:'https://www.google.com',
键入:“text/javascript”,
异步:空
},'innerHTML',function(){});

好吧,有多种方法可以包含动态javascript, 我在很多项目中都使用这个

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);
您可以调用create一个通用函数,该函数可以帮助您根据需要加载尽可能多的javascript文件。这里有一个完整的教程


我通过递归附加每个脚本来尝试

注意如果您的脚本一个接一个地依赖,那么位置将需要同步

主依赖项应该在数组中的最后一个,以便初始脚本可以使用它

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']
让计数=0
常量recursivelyAddScript=(脚本,cb)=>{
const el=document.createElement('script')
el.src=脚本
如果(计数<脚本长度){
计数++
el.onload=recursivelyAddScript(脚本[计数])
document.body.appendChild(el)
}否则{
console.log('All script loaded')
返回
}
}

recursivelyAddScript(scripts[count])
这里是一个小片段,与Google Analytics和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");

替换
https://example.com/foo.js
使用脚本路径。

这是我的工作。

你可以查一下

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_标记);
window.onload=函数(){
if(window.jQuery){
//jQuery已加载
警报(“在头部添加脚本标记!”);
}否则{
//jQuery未加载
警报(“不在头部添加脚本标记”);
}

}
异步加载脚本时,它们不能调用document.write。这些调用将被忽略,并向控制台写入警告

可以使用以下代码动态加载脚本:

var scriptElm = document.createElement('script');
scriptElm.src = 'source.js';
document.body.appendChild(scriptElm);
只有当源文件属于单独的文件时,这种方法才能很好地工作

但是,如果您将源代码作为内联函数,希望动态加载这些函数,并希望向脚本标记添加其他属性,例如类、类型等,那么以下代码段将对您有所帮助:

var scriptElm = document.createElement('script');
scriptElm.setAttribute('class', 'class-name');
var inlineCode = document.createTextNode('alert("hello world")');
scriptElm.appendChild(inlineCode); 
document.body.appendChild(scriptElm);
一行(尽管与上述答案没有本质区别):

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

以正确的顺序加载相互依赖的脚本

基于响应,但修复了加载。 它是在脚本实际加载之前触发的

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']
让计数=0
常量recursivelyAddScript=(脚本,cb)=>{
const el=document.createElement('script')
el.src=脚本
如果(计数<脚本长度){
计数++
el.onload=()=>recursivelyAddScript(脚本[计数])
document.body.appendChild(el)
}否则{
console.log('All script loaded')
返回
}
}

recursivelyAddScript(scripts[count])
没有人提到它,但是您也可以使用
URL
Blob
将实际的源代码粘贴到脚本标记中:

const jsCode=`
//JS代码在这里。也许你是从一些HTML字符串中提取出来的。
`
const url=url.createObjectURL(新Blob([jsCode]))
常量脚本=document.createElement('script')
script.src=url
revokeObjectURL(URL)//完成后处理它
至于
jsCode
,您可能从一些HTML中获得它

下面是一个更完整的示例,说明如何在HTML源代码中处理任意数量的脚本:

main()
异步函数main(){
常量scriptTagOpen=/]*>/g
常量scriptTagClose=/]*>/g
常量scriptTagRegex=/]*>[\s\s]*?]*>/g
const response=wait fetch('path/to/some.html')
const html=wait response.text()
someElement.innerHTML=html
//我们需要获取脚本标记并手动将它们添加到DOM中
//因为否则innerHTML将不会执行它们。
常量码=
html
.match(scriptTagRegex)
?.map(code=>code.replace(scriptTagOpen.)).replace(scriptTagClose.))
.map(代码=>URL.c