Javascript 脚本标记仅在插入DOM后第一次运行

Javascript 脚本标记仅在插入DOM后第一次运行,javascript,html,dom,innerhtml,Javascript,Html,Dom,Innerhtml,非常奇怪的是,为什么脚本标记在插入dom后只运行一次 script = document.createElement('script'); script.type = 'text/javascript' script //output: <script type=​"text/​javascript">​</script>​ document.body.appendChild(script); script.innerHTML = 'console.log("Att

非常奇怪的是,为什么脚本标记在插入dom后只运行一次

script = document.createElement('script');
script.type = 'text/javascript'

script
//output: <script type=​"text/​javascript">​</script>​

document.body.appendChild(script);

script.innerHTML = 'console.log("Attempt one")'
//output Attempt one

script.innerHTML = 'console.log("Attempt two")'

script.innerHTML = 'console.log("Attempt three")'

//second and third attempts emit no output
script=document.createElement('script');
script.type='text/javascript'
剧本
//输出:​​
document.body.appendChild(脚本);
script.innerHTML='console.log(“尝试一次”)'
//输出尝试一
script.innerHTML='console.log(“第二次尝试”)'
script.innerHTML='console.log(“尝试三次”)'
//第二次和第三次尝试不输出
是否有任何方法允许对脚本文本进行其他更改


我已经尝试将它包装成一个函数,但没有成功…我找不到任何解释来解释为什么
日志第一次运行,而下面的日志就不会这样运行。您通常不必向现有标记添加新代码;创建新标记或更好地利用函数和事件。

就是这样。您通常不必向现有标记添加新代码;创建新标记或更好地利用函数和事件。

在脚本执行的任意点更改
DOM节点的内部文本不会触发重新执行整个脚本,不会


创建一个新的脚本标记,或者更好地改进您的方法。您永远不会发现自己需要注入脚本标记;相反,只需以正常方式执行这些函数调用。

在脚本执行的任意点更改
DOM节点的内部文本不会触发重新执行整个脚本,不会


创建一个新的脚本标记,或者更好地改进您的方法。您永远不会发现自己需要注入脚本标记;相反,只需以正常的方式执行这些函数调用。

这里要澄清的是,上面的代码可能是一种糟糕的方法,等等。 但问题实际上是指这种行为以及为什么会发生

在过去几分钟的讨论之后,我可以注意到,在每个脚本标记都附加到DOM并具有内容之后,javascript只会为每个脚本标记运行一次

例如,您可以将
脚本
标记附加到DOM中,而不包含任何内容。。。
这不会触发javascript。但是,一旦您使用
innerText
innerHTML
等向该标记添加内容,它就会立即启动javascript

非常有趣的是,每次javascript为特定的标记运行时,每个脚本标记似乎都会处理一个设置为
false
的标志,然后在发生这种情况后,不管为什么,它都不会再次触发

以下是一些有趣的测试:

正常行为 深度克隆节点 因此,正如您所看到的,如果您通过生成精确副本或不生成精确副本来克隆脚本,则脚本标记将保留
alreadyExecuted
属性,无论原因为何

这让我想到,是否有任何方法可以将这个标志设置为其原始初始值,而不是创建一个新的
script
标记

但在最坏的情况下,如果你真的需要使用这个。创建一个动作来获取
脚本
,创建一个具有相同属性的新动作(如果有的话),然后用新内容替换旧内容并不困难。javascript将像第一次一样运行

下面的脚本可以很容易地调用,它将用一个新的脚本标记替换旧的脚本标记,并通过简单地提供要替换内容的脚本标记来执行新的javascript

function innerScript(element) {

    var newElement = document.createElement('script'),
        attr;

    for (attr = 0; attr < element.attributes.length; attr += 1) {
        newElement.setAttribute(element.attributes[attr].name, element.attributes[attr].value);
    }

    element.parentNode.replaceChild(newElement, element);
    return newElement;

}
函数innerScript(元素){
var newElement=document.createElement('script'),
attr;
对于(attr=0;attr
这里只想澄清一下,上面的代码可能是一种糟糕的方法,等等。 但问题实际上是指这种行为以及为什么会发生

在过去几分钟的讨论之后,我可以注意到,在每个脚本标记都附加到DOM并具有内容之后,javascript只会为每个脚本标记运行一次

例如,您可以将
脚本
标记附加到DOM中,而不包含任何内容。。。
这不会触发javascript。但是,一旦您使用
innerText
innerHTML
等向该标记添加内容,它就会立即启动javascript

非常有趣的是,每次javascript为特定的标记运行时,每个脚本标记似乎都会处理一个设置为
false
的标志,然后在发生这种情况后,不管为什么,它都不会再次触发

以下是一些有趣的测试:

正常行为 深度克隆节点 因此,正如您所看到的,如果您通过生成精确副本或不生成精确副本来克隆脚本,则脚本标记将保留
alreadyExecuted
属性,无论原因为何

这让我想到,是否有任何方法可以将这个标志设置为其原始初始值,而不是创建一个新的
script
标记

但在最坏的情况下,如果你真的需要使用这个。创建一个动作来获取
脚本
,创建一个具有相同属性的新动作(如果有的话),然后用新内容替换旧内容并不困难。javascript将像第一次一样运行

下面的脚本可以很容易地调用,它将用一个新的脚本标记替换旧的脚本标记,并通过简单地提供要替换内容的脚本标记来执行新的javascript

function innerScript(element) {

    var newElement = document.createElement('script'),
        attr;

    for (attr = 0; attr < element.attributes.length; attr += 1) {
        newElement.setAttribute(element.attributes[attr].name, element.attributes[attr].value);
    }

    element.parentNode.replaceChild(newElement, element);
    return newElement;

}
函数innerScript(元素){
var newElement=document.createElement('script'),
attr;
对于(attr=0;attr
为什么不呢
var clone = script.cloneNode();
// <script></script>

clone.innerHTML = 'alert("attemp two")';

document.body.replaceChild(clone, script);
// no output
var newScript = document.createElement('script');

newScript.innerHTML = 'alert("attempt three")';

document.body.replaceChild(newScript, script);
// output alert
function innerScript(element) {

    var newElement = document.createElement('script'),
        attr;

    for (attr = 0; attr < element.attributes.length; attr += 1) {
        newElement.setAttribute(element.attributes[attr].name, element.attributes[attr].value);
    }

    element.parentNode.replaceChild(newElement, element);
    return newElement;

}