这看起来很愚蠢,但我找不到如何使用 jQuery 进行不涉及某些服务器端请求的异步函数调用。我有一个缓慢的函数,它会遍历大量 DOM 元素,并且我希望浏览器在该函数运行时不会冻结。我想在调用慢速函数之前显示一个小指示器,然后当慢速函数返回时,我想隐藏该指示器。我有以下内容:
$('form#filter', parentNode).submit(function() {
var form = $(this);
indicator.show();
var textField = $('input#query', form);
var query = jQuery.trim(textField.val());
var re = new RegExp(query, "i");
slowFunctionCall(); // want this to happen asynchronously; all client-side
indicator.hide();
return false;
});
目前我提交表单,指示器没有显示,浏览器冻结,然后slowFunctionCall
完成了。
Edit: I used 维文的回答 https://stackoverflow.com/questions/6836299/jquery-asynchronous-function-call-no-ajax-request/6836335#6836335,具体来说站点链接 http://www.sitepoint.com/multi-threading-javascript/得到如下解:
var indicator = $('#tagFilter_loading', parentNode);
indicator.hide();
var spans = $('div#filterResults span', parentNode);
var textField = $('input#query', parentNode);
var timer = undefined, processor = undefined;
var i=0, limit=spans.length, busy=false;
var filterTags = function() {
i = 0;
if (processor) {
clearInterval(processor);
}
indicator.show();
processor = setInterval(function() {
if (!busy) {
busy = true;
var query = jQuery.trim(textField.val()).toLowerCase();
var span = $(spans[i]);
if ('' == query) {
span.show();
} else {
var tagName = span.attr('rel').toLowerCase();
if (tagName.indexOf(query) == -1) {
span.hide();
}
}
if (++i >= limit) {
clearInterval(processor);
indicator.hide();
}
busy = false;
}
}, 1);
};
textField.keyup(function() {
if (timer) {
clearTimeout(timer);
}
/* Only start filtering after the user has finished typing */
timer = setTimeout(filterTags, 2000);
});
textField.blur(filterTags);
这会显示和隐藏指示器,并且不会冻结浏览器。您可以看到 DOM 元素在工作时被隐藏,这正是我想要的。