【发布时间】:2011-10-13 18:12:13
【问题描述】:
这似乎很愚蠢,但我找不到如何使用不涉及某些服务器端请求的 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就完成了。
编辑:我使用Vivin's answer,特别是Sitepoint link 来获得以下解决方案:
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 元素,这正是我想要的。
【问题讨论】:
-
我认为所有的 JS 都在一个线程中运行。所以不可能异步运行函数。但我可能错了:)
-
根据您访问使您的功能变慢的 DOM 元素的方式,您可能可以加快这部分的速度。您是否使用类或属性过滤器使用 JQuery 访问元素(慢)?该函数是否多次运行,是否有任何方法可以缓存您正在与之交互的元素/ID?您能否通过更改所有受影响元素使用的 CSS 类来执行相同的 DOM 更新?
标签: javascript jquery forms function asynchronous