在循环数组时使用jQuery .get()添加的元素在页面刷新时以不同的顺序加载

Elements prepended using jQuery .get() while looping through array are loaded in different order on page refresh

本文关键字:刷新 加载 顺序 元素 添加 数组 循环 jQuery get      更新时间:2023-09-26

我想在我的网页上显示一些项目的子部分。我在html文件中有一个项目名称数组和一些相应的数据,如下面的示例所示。我有一个带有一些预览内容的按钮,如果用户点击它,它会打开包含所有项目详细信息的完整容器。

要做到这一点,我想通过一个切片数组的反向循环,并在我的网页上的div元素前置代码。内容通常加载得很好,但有时当我刷新页面时,它会以不同于数组中定义的顺序显示预览。此外,有时"previewtitle"answers"previewcontent"返回未定义,但并非总是如此。我哪里做错了?

我想在每次刷新时以相同的顺序动态地添加项目。

var $projectNames = [ "coolprojecthere", "andanotherone", "moreprojects", "lastone" ];

projects/coolprojecthere.html如下所示:

<div id="title">Project title here</div>
<div id="content">Content html here</div>

projects/previews/coolproject there.html如下所示:

<div id="title">Project title here</div>
<div id="content">Content text here</div>

我像这样循环遍历它们,把它们加在前面:

$projectNames = $projectNames.slice(0, 7);
    $.each($projectNames.reverse(), function (index, projectname) {
        var previewtitle, previewcontent;
        $.get("projects/previews/" + projectname + ".html", function (prevdata) {
            previewtitle = $(prevdata).filter('#title').text();
            previewcontent = $(prevdata).filter('#content').text();
        });
        $.get("projects/" + projectname + ".html", function (data) {
            var project = "<section id='"project'" class='"'"> '
                                        <t>" + previewtitle + "</t><br /> '
                                        <p>" + previewcontent + "</p> '
                                </div> '
                                <div class='"content'"> '
                                    <h5>" + $(data).filter('#title').text() + "</h5> '
                                    <div class='"content-container'">"
                                        + $(data).filter('#content').html() +
                                    "</div> '
                                </div> '
                            </section>"
            $('#main-container').prepend(project);
        });

从jQuery文档中你必须指定async选项设置为false以获得同步AJAX请求。

$.ajax({ url: 'projects/previews/" + projectname + ".html', 
  async: false,
  dataType: 'json',
  success: function(data) {
     // your code here
    }
});

默认情况下,所有请求都是异步发送的(即默认设置为true)。如果您需要同步请求,请将此选项设置为false。

否则,您也可以执行jQuery的AJAX设置,并通过调用一次(在初始代码上方)将其设置为同步模式:
jQuery.ajaxSetup({async:false});

它将以同步模式执行所有进一步的AJAX调用。你可以像以前一样继续使用jQuery.get();方法。

注意:请阅读Felix Kling的回答,关于何时同步调用可能是一个坏主意。

使Ajax调用同步是一个坏主意。相反,您应该将链接起来并嵌套,以便每个一个接一个地执行。

让我们使用promises: 来组织你的代码。
function getPreviewData(projectName) {
  return $.get(
    "projects/previews/" + projectname + ".html"
  ).then(function(prevdata) {
    return {
      title: $(prevdata).filter('#title').text(), 
      content:  $(prevdata).filter('#content').text()
    };
  );
}
function getProjectHTML(projectName, previewTitle, previewContent) {
  return $.get("projects/" + projectname + ".html").then(function (data) {
    // ...
  });
}
$projectNames = $projectNames.slice(0, 7);
var head = new $.Deferred();
var chain = head.promise();
$.each($projectNames.reverse(), function (index, projectName) {
  chain = chain.then(function() {
    return getPreviewData(projectName).then(function(previewData) {
      return getProjectHTML(projectName, previewData.title,  previewData.content);
    });
  });
});
head.resolve();