为什么这个Javascript代码没有按顺序执行?

时间:2014-10-19 12:37:45

标签: javascript jquery ajax json callback

使用jQuery我正在调用我的服务器,它返回一些json。然后我使用.done定义了一个回调来创建一个回调,它似乎没有顺序行为。

我的html(<div id="properties"></div>)中有一个div,我尝试用结果表填充该div:

request.done(function(data){
    if (data['result'].length == 0) {
        $("#properties").html("<h3>No results were found..</h3>");
    } else {
        $("#properties").html("<table><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody>");
        data['result'].forEach(function(prop){
            $("#properties").append("<tr>");
            $("#properties").append("<td>prop.status</td>");
            $("#properties").append("<td>prop.title</td></tr>");    
        });
        $("#properties").append("</tbody></table>");
    }
});

我得到的结果是:

<div id="properties">
    <table class="table table-hover"><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody></tbody></table>
    <tr></tr>
    <td>prop.status</td>
    <td>prop.title</td>
</div>

我知道.done仅在ajax调用返回一些内容时调用,但是 withint 调用它,它应该按顺序运行吗?这里有两件事我真的不明白:

  1. </table>代码后,为什么表格行和数据会写入
  2. 为什么<tr></tr><td>标记之前写入,即使最后</tr>与最后<td> in the last一起附加在一起在foreach循环中追加()`?
  3. 所以我也试着一次性附加整个表格行:

    $("#properties").append("<tr><td>prop.status</td><td>prop.title</td></tr>");
    

    这样做效果好一点,但仍然只产生这个:

    <div id="properties">
        <table class="table table-hover"><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody></tbody></table>
        <tr><td>prop.status</td><td>prop.title</td></tr>
    </div>
    

    Javascript之前让我感到困惑,但这真让我大吃一惊。欢迎任何提示!

3 个答案:

答案 0 :(得分:4)

你在这里看到的是关闭你的标签,因为这些元素是在append / html上整体创建的。为了获得你期望在字符串中构建的行为,请说出更像这样的内容:

request.done(function(data){
    if (data['result'].length == 0) {
        $("#properties").html("<h3>No results were found..</h3>");
    } else {
        var propertiesTableHTML = "<table><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody>";
        data['result'].forEach(function(prop){
            propertiesTableHTML += "<tr>";
            propertiesTableHTML += "<td>" + prop.status + "</td>";
            propertiesTableHTML += "<td>" + prop.title + "</td>";
            propertiesTableHTML += "</tr>";
        });
        propertiesTableHTML += "</tbody></table>";
        $("#properties").html(propertiesTableHTML);
    }
});

答案 1 :(得分:1)

您希望.html().append()像[{1}}一样工作,但他们不会。与HTML一起使用时,他们希望正确的 HTML。更正了损坏的HTML(例如缺少结束标记),这会导致意外行为。这部分代码例如:

document.write()

产生以下结果:

$("#properties")
    .html("<table><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody>");

同样,这段代码:

<table>
    <thead>
        <tr>
            <th>Status</th>
            <th>Title</th>
        </tr>
    </thead>
    <tbody>
    </tbody><!-- tag closed automatically -->
</table><!-- tag closed automatically -->

产生以下结果:

 $("#properties").append("<tr>");
 $("#properties").append("<td>prop.status</td>");
 $("#properties").append("<td>prop.title</td></tr>");   

一种可能的解决方案是修改你的代码:

...
</table>
<tr></tr><!-- tag closed automatically -->
<td>prop.status</td>
<td>prop.title</td><!-- </tr> ignored -->

答案 2 :(得分:0)

您无法向DOM添加标记,您只能添加元素。当您尝试添加<table>标记时,它会添加一个完整的table元素。当您尝试添加结束标记时,它将被忽略(或者可能导致错误,具体取决于浏览器),因为它不是可以解析为元素的代码。

重写代码以添加元素而不是标记:

$("#properties").html("<table><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody></tbody></table>");
var tbody = $("#propertis tbody");
data['result'].forEach(function(prop){
  var row = $("<tr>");
  row.append($("<td>").text(prop.status));
  row.append($("<td>").text(prop.title));
  tbody.append(row);
});

通过将表格单元格创建为元素并使用text方法设置内容,可以避免任何需要HTML编码的特殊字符的问题(例如<>&)弄乱HTML代码。