這似乎很愚蠢,但我無法找到如何做一個與jQuery不涉及一些服務器端請求的異步函數調用。我有一個緩慢的函數,它遍歷了很多DOM元素,並且我希望瀏覽器在該函數運行時不會凍結。我想在慢速函數被調用之前顯示一個小指示器,然後當慢速函數返回時,我想隱藏指示器。我有以下幾點:jQuery異步函數調用,沒有AJAX請求
$('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運行在一個單一的線程。所以不可能運行異步函數。但我可能錯了:) – PeeHaa
根據你如何訪問正在減慢你的函數的DOM元素,你可能會加快這一部分。你使用類或屬性過濾器(緩慢)訪問與JQuery元素?函數是否運行多次,並且有什麼方法可以緩存與之交互的元素/ ID?你可以通過改變所有受影響的元素使用的CSS類來做同樣的DOM更新嗎? – tomfumb