原因:浏览器会将通过innerHTML动态插入的当成普通文本,不会维护到DOM里面,所以会存在调用的时候找不到。
解决办法:首先嵌入后,通过DOM找到所有的script标签,然后一一创建script标签,并将script里面的内容重新赋值,将这个新的script节点追加到页面的head节点中,这样就可以调用里面的函数了。
// 解决方法一:将script里面的标签取出来,然后用appendchild的方式加入
function runScript(script){
// 直接 document.head.appendChild(script) 是不会生效的,需要重新创建一个
const newScript = document.createElement('script');
newScript.innerHTML = script.innerHTML;
// 存在 src 属性的话
const src = script.getAttribute('src');
if (src) newScript.setAttribute('src', src);
document.body.appendChild(newScript);
document.body.removeChild(newScript);
}
function setHTMLWithScript(container, rawHTML){
container.innerHTML = rawHTML;
const scripts = container.querySelectorAll('script');
for (let script of scripts) {
runScript(script);
}
}
setHTMLWithScript(document.getElementById("app"),localStorage.getItem("htmlData"))
// 解决办法二 将html标签转换成dom节点,然后append上去(兼容性ie11以上)
var htmls = localStorage.getItem("htmlData");
var range = document.createRange();
range.selectNode(document.body);
var documentFragment = range.createContextualFragment(htmls);
document.body.appendChild(documentFragment)
以上两种方式都可以实现,app是要嵌入的div的id,htmlData是需要插入的html字符串,储存在localstorage里面
遗留问题:如果是src的script标签,加载对应的js文件,可能存在异步加载的问题,导致其他script先执行而报错。暂未找到合适的方法解决