我尝试在<div>上使用innerHTML加载一些脚本到页面中。脚本似乎加载到DOM中,但它从未执行(至少在Firefox和Chrome中)。有一种方法让脚本执行时插入他们与innerHTML?

示例代码:

<!DOCTYPE html > < html > <身体onload = " . getelementbyid(机)。innerHTML = '<script>alert(\'hi\')<\/script>'"> 难道不应该出现“hi”的提醒吗? < div id = "装载机" > < / div > 身体< / > < / html >


当前回答

从innerHTML执行(Java Script)标签

将脚本元素替换为具有class="javascript"类属性的div,并以</div>关闭

不要改变你想要执行的内容(以前是在script标签,现在是在div标签)

在你的页面中添加一个样式…

<style type="text/css"> .javascript {display: none;} > < /风格

现在使用jquery运行eval (jquery js应该已经包含在内)

   $('.javascript').each(function() {
      eval($(this).text());

    });`

你可以在我的博客上探索更多。

其他回答

下面是一个递归地将所有脚本替换为可执行脚本的方法:

function nodeScriptReplace(node) {
        if ( nodeScriptIs(node) === true ) {
                node.parentNode.replaceChild( nodeScriptClone(node) , node );
        }
        else {
                var i = -1, children = node.childNodes;
                while ( ++i < children.length ) {
                      nodeScriptReplace( children[i] );
                }
        }

        return node;
}
function nodeScriptClone(node){
        var script  = document.createElement("script");
        script.text = node.innerHTML;

        var i = -1, attrs = node.attributes, attr;
        while ( ++i < attrs.length ) {                                    
              script.setAttribute( (attr = attrs[i]).name, attr.value );
        }
        return script;
}

function nodeScriptIs(node) {
        return node.tagName === 'SCRIPT';
}

示例调用:

nodeScriptReplace(document.getElementsByTagName("body")[0]);

单线解决方案如下:

document.getElementsByTagName("head")[0].append(document.createRange().createContextualFragment('<script src="https://google.com/file.js"></script>'));

Krasimir Tsonev有一个伟大的解决方案,可以克服所有的问题。 他的方法不需要使用eval,因此不存在性能和安全问题。 它允许你用js设置innerHTML字符串包含html,并立即将其转换为DOM元素,同时还执行代码中存在的js部分。简短,简单,完全按你想要的工作。

享受他的解决方案吧:

http://krasimirtsonev.com/blog/article/Convert-HTML-string-to-DOM-element

重要提示:

您需要用div标签包装目标元素 你需要用div标签包装src字符串。 如果你直接写src字符串,它包括js部分,请注意正确地写结束脚本标记(在/之前有\),因为这是一个字符串。

下面是一个更现代(和简洁)的mmm解决方案:

function executeScriptElements(containerElement) {
  const scriptElements = containerElement.querySelectorAll("script");

  Array.from(scriptElements).forEach((scriptElement) => {
    const clonedElement = document.createElement("script");

    Array.from(scriptElement.attributes).forEach((attribute) => {
      clonedElement.setAttribute(attribute.name, attribute.value);
    });
    
    clonedElement.text = scriptElement.text;

    scriptElement.parentNode.replaceChild(clonedElement, scriptElement);
  });
}

注意:我还尝试过使用cloneNode()或outerHTML的替代解决方案,但没有成功。

是的,你可以,但你必须在DOM之外做,而且顺序必须是正确的。

var scr = '<scr'+'ipt>alert("foo")</scr'+'ipt>';
window.onload = function(){
    var n = document.createElement("div");
    n.innerHTML = scr;
    document.body.appendChild(n);
}

...将提醒'foo'。这行不通:

document.getElementById("myDiv").innerHTML = scr;

即使这样也不行,因为先插入节点:

var scr = '<scr'+'ipt>alert("foo")</scr'+'ipt>';
window.onload = function(){
    var n = document.createElement("div");
    document.body.appendChild(n);
    n.innerHTML = scr;  
}