附加到元素的脚本标记会在.append()之后的下一行之前运行吗?

Will a script tag appended to an element run before the next line after .append()?

本文关键字:一行 运行 之后 脚本 append 元素      更新时间:2023-09-26

我从服务器获取HTML文档,将其存储在变量data中,然后将其附加到页面上的<ul>元素。以下是data的样子:

<script>
    hasNext = true // global variable
</script>
<li class="result">one</li>
<li class="result">two</li>

然后在页面的主Javascript中,我这样做:

ulElement.append(data);
if (hasNext) {
    ulElement.append(nextPageButton);
}

它似乎工作,但我只是想确保<script>标记中的代码将始终在我的if语句之前运行。我在网上找不到任何关于这种可能的竞争状况的信息。想法吗?

不管这是不是一个好主意....

为了让浏览器解释动态插入的DOM,它必须解析您提供的内容。这是一个同步过程(假设你的JS不做任何AJAX请求,setTimeouts等)。来自Google Dev博客:

当HTML解析器遇到脚本标记时,它会暂停执行的过程构造DOM并将控制权交给JavaScript引擎;一旦JavaScript引擎完成运行,浏览器就会运行从它停止的地方继续并继续DOM构造。

这意味着浏览器保证在移动到下一个JS命令:if (hasNext) {...之前处理和执行脚本标记中的JS(以及在字符串中添加DOM)。

在您的示例中,<script>标记相对于data中动态插入的DOM的其余部分并不重要,因为DOM和该脚本之间没有依赖关系。只要它在data中,浏览器将在继续到append之后的行之前处理这些命令。例如:

<li class="result">one</li>
<li class="result">two</li>
<script>
    hasNext = true // global variable
</script>

由于您的代码在append调用后检查动态"注入"变量,因此变量(hasNext)保证存在(只要它在data中的<script>标记中)。

例如:

$( ".test" ).append( "<p>Test</p><script>var globalVariable = 123;" );
$( ".test" ).append( globalVariable );

会写:

<p>Test</p>123

最可能的竞态条件是来自一些没有指定hasNext变量的服务器交互,在这种情况下,代码将使用该变量的假值:

if (undefined) { 
    alert('I won''t be called'); 
} else { 
    alert('I will be called'); 
}

- or,更危险的版本-

您的if (hasNext) { ... }将使用该变量的前一个值,该值来自先前使用不同的data调用append。这是相当危险的,可能是避免这种方法的最佳原因。

如果你真的想这样做,也许你可以使用window.onload.

等待页面加载完成。
ulElement.append(data);
$(function(){
    if (hasNext) {
        ulElement.append(nextPageButton);
    }
});