首页 > 解决方案 > 等待元素出现在 jQuery 中

问题描述

我加快了服务器响应时间,突然遇到了一个奇怪的问题:我遇到了一个问题,即在浏览器绘制某些需要首先显示在屏幕上的元素之前执行代码。问题不是代码需要在 $.ajax().done() 中,我本质上需要一个done用于将元素插入 DOM 的方法。

到目前为止,我发现的最佳选择是对去年使用 async/await 的类似问题的回答

const checkElement = async selector => {
  while ( document.querySelector(selector) === null) {
    await new Promise( resolve =>  requestAnimationFrame(resolve) )
  }
  return document.querySelector(selector); 
};

我可以在我自己的代码中调用它,然后像这样:

   checkElement('#showFileBrowserContent').then( function (selector) {
        loadDirectory (path, "", nextMode, articleId, siteId, currentSetting, fileBrowserPanel, callback, mode);
    });

这似乎工作得很好,但我想知道是否有一种方法可以让它在 jQuery 函数中工作,只是为了整洁,例如:

$('#showFileBrowserContent').checkElement().done( function () { loadDirectory (path, "", nextMode, articleId, siteId, currentSetting, fileBrowserPanel, callback, mode); });

我以前从未尝试过扩展 jQuery,所以我可能完全错误地这样做了,但我试图做到这一点:

jQuery.fn.checkElement = async function () {
    var o = $(this[0]) // This is the element
    
    // Also tried o === null without the $().
    while ( $( o ) === null) {
        await new Promise( resolve =>  requestAnimationFrame(resolve) )
    }
    
    return this; 
};

这没有用。在 jQuery 函数中使用 async/await 是否有问题?还是我的代码有问题?


更新:这是有问题的代码,我试图确保在继续之前完成插入 DOM。它使用BootstrapDialog

    fileBrowserPanel = new BootstrapDialog({            
        title: title,
        buttons: buttons,
        cssClass: 'fileBrowser',
        onhide: function(mode){ 
                if (editorPanel !== null) { 
                    editorPanel.open(); editorPanel.setAutodestroy(true); 
                }   
            }
        });

    var editorContents = '<div class="row"><div id="fileBrowserCurrentLocation" class="col-xs-8"></div><div id="fileBrowserToolbar" class="col-xs-4"><p><button type="button" class="btn btn-default" aria-label="Upload a File" id="launchFileUpload"><span class="glyphicon glyphicon-cloud-upload" aria-hidden="true"></span> Upload a File</button></p></div></div>';
    editorContents += '<div class="row"><div id="showFileBrowserContent" class="col-xs-12"><table id="loaderTable">' + loaderGraphic + '</table></div></div>';


    fileBrowserPanel.setMessage(editorContents);
    fileBrowserPanel.setType(BootstrapDialog.TYPE_INFO);
    var response = fileBrowserPanel.open();         

该代码在实际文档数据应该进入的位置插入了一个微调器图形#showFileBrowserContent。然后它调用loadDirectory(),它通过 AJAX 调用来获取实际内容并用#showFileBrowserContent返回的内容替换 's 的内容。但是,如果没有计时器或await函数,AJAX 调用似乎已完成并且#showFileBrowserContent还不存在。当我的服务器响应时间接近 600 毫秒时,这不是问题,但是当我将其降低到接近 200-300 毫秒时,微调器永远不会消失,我注意到它似乎是因为 AJAX 调用之前 #showFileBrowserContent完成的存在。

标签: javascriptjqueryasync-await

解决方案


推荐阅读