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

时间:2015-09-30 15:16:03

标签: javascript jquery html

我从服务器获取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语句之前运行。我无法在网上找到有关这种可能的竞争条件的任何信息。想法?

2 个答案:

答案 0 :(得分:1)

独立于这是否是一个好主意......

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

  

当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>

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

例如:

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

将写:

<p>Test</p>123

最可能的竞争条件来自某些服务器交互未指定hasNext变量,在这种情况下,代码将使用该变量的falsey值:

if (undefined) { 
    alert('I won\'t be called'); 
} else { 
    alert('I will be called'); 
}
-OR,风险更高的版本 -

您的if (hasNext) { ... }将使用之前调用append且不同data的变量的先前值。这是非常危险的,可能是避免这种方法的最佳理由。

答案 1 :(得分:0)

如果您真的想这样做,也许您可​​以使用window.onload等待页面加载。

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