首页 > 解决方案 > 隐藏 div 仅在 Ajax 响应的所有内容都已呈现后

问题描述

我希望只有在来自 ajax 调用的响应内容已在视图中完全填充和重新渲染后,我的 javascript 中的加载器 div 才会被隐藏。我尝试了以下代码,但即使渲染完成,加载程序也不会隐藏。

function fxnname()
{
    document.getElementById('report_div').style.display = 'block';
    document.getElementById('loading').style.display = 'block';
    var year = document.getElementById('year').value;

    if (window.XMLHttpRequest) 
    {
        xmlhttp=new XMLHttpRequest();
    } 
    else 
    {  
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange=function() 
    {
        if (this.readyState==4 && this.status==200)
        {
            document.getElementById("report_div").innerHTML=this.responseText;
            document.addEventListener("DOMContentLoaded", () => {
                document.getElementById('loading').style.display = 'none';
            });
        }
    }
    xmlhttp.open("GET","TheURL.PHP?q="+year,true);
    xmlhttp.send();
}

更新: 我在表的末尾添加了一个 id 为 tablend 的 div,以确保在表渲染完成时加载器关闭,以及在该表也渲染后的虚拟 div。它每 1000 次检查虚拟桌面 div 是否已呈现。我更新了代码如下:

if (this.readyState==4 && this.status==200)
{
    document.getElementById("report_div").innerHTML=this.responseText;
    var interval = setInterval(function () {
       var tablend = document.getElementById("tablend");
       if (tablend) {
        clearInterval(interval);
        document.getElementById('loading').style.display = 'none';
       }
    }, 1000)
}

这次看起来一切正常,但是在样式完成之前加载程序仍然关闭。此外,该页面仍然加载了大量数据,因此,如果我再次单击相同的按钮,应用程序响应太慢。

标签: javascriptajaxscripting

解决方案


The DOMContentLoaded event doesn't have any connection to AJAX requests. It fires when the browser has finished parsing initial page resources. See the documentation here. The div isn't being hidden because the callback that hides it is never called.

You could use javascript to fire your own event whenever the requested data is loaded and corresponding DOM elements are updated. In this case you could add the event listener to the document right away, before you even make the request. However, the alternative I would suggest is to use a more modern request API like fetch or async/await instead of the XMLHttpRequest object. These APIs allow you to express asynchronous control flows in a more declarative syntax that is easier to read and (arguably) also easier to write. E.g. using the fetch api:

fetch(my/resource/url)
.then(response => JSON.parse(response))
.then(json => functionToUpdateDOM(json))
.then(functionToHideLoadingDiv())
.catch(error => functionToHandleError(error))

推荐阅读