【问题标题】:How to set my HTML Table progressively with Javascript/AJAX and Java Servlet?如何使用 Javascript/AJAX 和 Java Servlet 逐步设置我的 HTML 表?
【发布时间】:2013-05-28 10:22:09
【问题描述】:

大家好!我在开发一个小 web 应用程序时遇到了问题。 目标是从服务器上的声明文件夹中搜索文件中的特定单词。

为此,我使用 java.io.File 和 BufferReader 实现了递归算法。 当我得到结果时,我使用我的 jsp 文件中的脚本将它们放在一个表中:

// Posting founded files in a table.
var files = response.getElementsByTagName("file");
// -> Creating the results table.
var table = "<table width=\"100%\">\n";

for (var i = 0, c = files.length; i < c; i++) {
// -> Building the number of apparence in each file.
var nb = files[i].getAttribute("nb");
var nbSentence = "";
if (nb == 1) { nbSentence = nb + " time in this file."; }
else { nbSentence = nb + " times in this file."; }

// Building and filling the table. 
if (i % 2 == 0) { table += "<tr class=\"pair\"><td><a href=" + files[i].firstChild.nodeValue + " target=\"_blank\" >"
                + files[i].getAttribute("name") + "</a></td><td>" + nbSentence + "</td></tr>\n"; }
else { table += "<tr class=\"impair\"><td><a href=" + files[i].firstChild.nodeValue + " target=\"_blank\" >"
                + files[i].getAttribute("name") + "</a></td><td>" + nbSentence + "</td></tr>\n"; }
}
table += "</table>\n";
// -> To end the procedure, we had the table to the right div.
document.getElementById("files").innerHTML = table;

我的问题是,使用此代码,所有结果都会一次性打印在目标表中。每次在算法中找到文件时,我都希望看到结果。

我尝试在 onreadystatestage 函数中将 readystate 更改为“3”:

xhr.onreadystatechange = function() {
if (xhr.readyState >= 3 && (xhr.status == 200 || xhr.status == 0)) {
    callback(xhr.responseXML);
    document.getElementById("loader").style.display = "none";
    document.getElementById("btn").value = "Search";
} else if (xhr.readyState < 3) {
    document.getElementById("loader").style.display = "inline";
    document.getElementById("btn").value = "Cancel";
}
};

但它不会改变任何东西。 有人有想法吗?我怎样才能一个一个地发送每个创建的文件?我在servlet类中不用做吗?

servlet 类中的 for 指令:

// If the input word name isn't empty, the algorithm is launched.
if (null != wordToSearch && !"".equals(wordToSearch))
{
lstFiles.clear();
searching(new File(contextPath), wordToSearch);

int n = lstFiles.size();
// Priting a message that indicate how many files have been found with the word to search.
emptyFieldMessage = n + " files has been found containing the word '" + wordToSearch + "'!";
output.append("<message>").append(emptyFieldMessage).append("</message>\n");
output.append("<lstFiles>\n");
// Then, files list with :
// - File path in "name" parameter,
// - Number of apparence of the word in "nb" parameter,
// - Formatted path as the value.
for(int i = 0; i < n; i++)
{
    output.append("<file name=\"" + lstFiles.get(i) + "\" nb=\"" + lstNbApparence.get(i) + "\" >").append(lstFilesPath.get(i)).append("</file>\n");
}
output.append("</lstFiles>\n");
}

为了更完整,整个脚本代码:

<script>
// Creating xhr variable.
var xhr = null;

// Creating the "Search" button function.
function request(callback) {

   // "Cancel" button case.
   if (xhr && xhr.readyState != 0)
   {
       xhr.abort();
   }
   // "Search" button case.
   else
   {
       // Calling the good function from external file.
       xhr = getXMLHttpRequest();

       // Callback and loading icon management.
       xhr.onreadystatechange = function() {
        if (xhr.readyState >= 3 && (xhr.status == 200 || xhr.status == 0)) {
            callback(xhr.responseXML);
            document.getElementById("loader").style.display = "none";
            document.getElementById("btn").value = "Search";
        } else if (xhr.readyState < 3) {
            document.getElementById("loader").style.display = "inline";
            document.getElementById("btn").value = "Cancel";
        }
      };

      // Calling the Servlet in charge of the recursion algorithm.
      var input = encodeURIComponent(document.getElementById("wordName").value);
      xhr.open("GET", "/webApp_Search_Merge/ActionServlet?wordName=" + input, true);
      xhr.send(null);
      }
}

// Creating the reponse function.
function readData(response) {

if (null != response)
{
    // Posting the message include in the XML file sending back by the Servlet.
    var message = response.getElementsByTagName("message");
    document.getElementById("message").innerHTML = message[0].firstChild.nodeValue;

    // Posting founded files in a table.
    var files = response.getElementsByTagName("file");
    // -> Creating the results table.
    var table = "<table width=\"100%\">\n";

    for (var i = 0, c = files.length; i < c; i++) {
        // -> Building the number of apparence in each file.
        var nb = files[i].getAttribute("nb");
        var nbSentence = "";
        if (nb == 1) { nbSentence = nb + " time in this file."; }
        else { nbSentence = nb + " times in this file."; }

        // Building and filling the table. 
        if (i % 2 == 0) { table += "<tr class=\"pair\"><td><a href=" + files[i].firstChild.nodeValue + " target=\"_blank\" >"
            + files[i].getAttribute("name") + "</a></td><td>" + nbSentence + "</td></tr>\n"; }
        else { table += "<tr class=\"impair\"><td><a href=" + files[i].firstChild.nodeValue + " target=\"_blank\" >"
            + files[i].getAttribute("name") + "</a></td><td>" + nbSentence + "</td></tr>\n"; }
    }
    table += "</table>\n";
    // -> To end the procedure, we had the table to the right div.
    document.getElementById("files").innerHTML = table;
}

}

提前感谢您的帮助,Thomas。

【问题讨论】:

  • 我不明白这个问题。请简洁明了。另外,应该发布您的 AJAX 调用代码
  • 嗨,对不起。我在上面发布了整个脚本。现在,我想要的是在表格中一一看到结果,而不是一次。每次我在 servlet 算法中找到一个文件时,我都想将它发布在表中,而不是等待整个算法完成。我希望这更清楚,顺便感谢您的帮助。托马斯。
  • 抱歉这么晚才回复,现在是发布时间。如果我了解您想要做什么,您的目标是要求服务器从文件中检索一些数据。例如,当服务器收到请求时,它会转到指定的文件,检查该文件中的所有行并找到 2000 行。然后,您想为每一行检索 1 个响应以 1 接 1 加载它们并“模拟”就好像您的表正在 1 接 1 填充一样。我不知道您是否发现了您想要的错误,如果它是什么你想实现,但你不能说服务器检索 2000 个响应。您将重载它 => 下一条评论以获取更多信息。
  • 运气好的话,即使您尝试模拟,您也会立即获得数据。您要做的是将数据检索到 AJAX 调用中,即使它被立即处理,并将其发送到具有间隔的函数,以便在 X 毫秒后将数据加载到表中。如果你愿意,我可以试着给你一个答案。
  • 这与我正在尝试做的事情非常接近。我不是想恢复 2000 行。我正在检查起始文件夹中的每个文件。在这些文件中,我确实阅读了每一行并检查我想要的单词是否在其中。如果这是真的,那么我将文件放在最终列表中,并且它是我发送到页面的那个列表(文件,而不是行)。然后,我将结果发布在表格中。如果我找到 35 个文件,我希望将它们一个一个地发送和发布,而不是在检查完所有文件后。如果除了模拟它别无他法,那就去吧,我想要你的答案!感谢您的宝贵时间。

标签: javascript ajax jsp servlets


【解决方案1】:

我尝试设置一个有效的演示,但没有结果。我也在寻找为什么我找不到“睡眠”function 并在 1000 毫秒或任何你想要的时间后重新执行的方法。已经找到了答案,但我认为这并不是您所期望的:

睡眠功能会杀死浏览器,可能还会杀死机器。 Javascript是单线程的,所以浏览器会阻塞 执行,循环本身只会占用大量 CPU。我有 听说过一些图书馆实际上在 异步方式,但我现在不记得名字了。


这是一个非常糟糕的主意。 JavaScript 是单线程的,所以 for 循环正在运行,没有其他东西可以执行(js 计时器,浏览器 事件,甚至大多数浏览器中的 UI)。尝试睡5个或更多 秒,浏览器甚至会警告用户脚本是 慢跑。

只需使用 setTimeout。

还谈到了 Native Javascript 中的睡眠功能。看起来它就像一个框架或类似的东西。您可以下载并自行尝试。我不能说什么,因为我从未测试过,这只是我在互联网上找到的。

很抱歉告诉你一个坏消息。

【讨论】:

  • Hy DaGLiMiOuX,非常感谢您的帮助和时间。没关系,即使管理它会很棒,它也不是我的应用程序中最重要的部分。再次感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-24
  • 1970-01-01
  • 2012-10-18
  • 2023-03-20
  • 1970-01-01
相关资源
最近更新 更多