我想动态地在网页中包含一个脚本标签但是我无法控制它的src所以src =“source.js”可能看起来像这样。
document.write('<script type="text/javascript">')
document.write('alert("hello world")')
document.write('</script>')
document.write('<p>goodbye world</p>')
现在通常放
<script type="text/javascript" src="source.js"></script>
头部的工作得很好,但有没有其他方法我可以使用innerHTML等动态添加source.js?
答案 0 :(得分:158)
var my_awesome_script = document.createElement('script');
my_awesome_script.setAttribute('src','http://example.com/site.js');
document.head.appendChild(my_awesome_script);
答案 1 :(得分:69)
您可以使用document.createElement()
这样的功能:
function addScript( src ) {
var s = document.createElement( 'script' );
s.setAttribute( 'src', src );
document.body.appendChild( s );
}
答案 2 :(得分:57)
有一个onload
函数,可以在脚本成功加载时调用:
function addScript( src,callback) {
var s = document.createElement( 'script' );
s.setAttribute( 'src', src );
s.onload=callback;
document.body.appendChild( s );
}
答案 3 :(得分:11)
我编写的一个很好的小脚本来加载多个脚本:
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);
}
};
用法:
scriptLoader(['a.js','b.js'], function() {
// use code from a.js or b.js
});
答案 4 :(得分:5)
这对我有用。
您可以检查它。
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");
}
}
答案 5 :(得分:3)
您可以尝试以下代码段。
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(){});
答案 6 :(得分:3)
单线(尽管与上面的答案没有本质区别):
document.body.appendChild(document.createElement('script')).src = 'source.js';
答案 7 :(得分:2)
以正确的顺序加载相互依赖的脚本。
基于Satyam Pathak的响应,但修复了onload。 它是在脚本实际加载之前触发的。
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])
答案 8 :(得分:1)
执行此操作的唯一方法是将document.write
替换为您自己的函数,该函数会将元素附加到页面底部。使用jQuery非常简单:
document.write = function(htmlToWrite) {
$(htmlToWrite).appendTo('body');
}
如果您有html以问题示例的方式来处理document.write,则需要缓冲htmlToWrite
段。也许是这样的:
document.write = (function() {
var buffer = "";
var timer;
return function(htmlPieceToWrite) {
buffer += htmlPieceToWrite;
clearTimeout(timer);
timer = setTimeout(function() {
$(buffer).appendTo('body');
buffer = "";
}, 0)
}
})()
答案 9 :(得分:1)
嗯,有多种方法可以包含动态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);
您可以调用创建通用功能,它可以帮助您根据需要加载尽可能多的JavaScript文件。这里有一个完整的教程。
答案 10 :(得分:0)
我通过递归地附加每个脚本来尝试
注意:如果您的脚本彼此依存,则位置需要保持同步。
主要依赖项应位于数组的最后,以便初始脚本可以使用它
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments("--headless");
WebDriver wDriver = new ChromeDriver(chromeOptions);
答案 11 :(得分:0)
这是一个简短的代码段,与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
。
答案 12 :(得分:0)
异步加载脚本时,它们无法调用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);
target.appendChild(scriptElm);
答案 13 :(得分:0)
没有人提到它,但您也可以通过使用 URL
和 Blob
将实际源代码制作成一个 URL 来将其粘贴到脚本标记中:
const jsCode = `
// JS code in here. Maybe you extracted it from some HTML string.
`
const url = URL.createObjectURL(new Blob([jsCode]))
const script = document.createElement('script')
script.src = url
URL.revokeObjectURL(url) // dispose of it when done
至于 jsCode
,你可能是从一些 HTML 中得到的。
以下是一个更完整的示例,说明如何处理 HTML 源代码中的任意数量的脚本:
main()
async function main() {
const scriptTagOpen = /<script\b[^>]*>/g
const scriptTagClose = /<\/script\b[^>]*>/g
const scriptTagRegex = /<script\b[^>]*>[\s\S]*?<\/script\b[^>]*>/g
const response = await fetch('path/to/some.html')
const html = await response.text()
someElement.innerHTML = html
// We need to get the script tags and manually add them to DOM
// because otherwise innerHTML will not execute them.
const codes =
html
.match(scriptTagRegex)
?.map(code => code.replace(scriptTagOpen, '').replace(scriptTagClose, ''))
.map(code => URL.createObjectURL(new Blob([code]))) || []
for (const code of codes) {
const script = document.createElement('script')
script.src = code
someElement.append(script)
URL.revokeObjectURL(code)
}
}