gpt4 book ai didi

javascript - 异步 keyup 事件/如何短路顺序 keyup 事件以提高速度

转载 作者:行者123 更新时间:2023-11-30 18:19:00 28 4
gpt4 key购买 nike

在我为工作而构建的网站上,我们有一个搜索栏,用户可以在其中输入内容以搜索存储在一组元素数据中的各个字段。当他们开始输入时,问题出现在较慢的浏览器中。

我尝试做的是以下操作,使用 jQuery Deferred 对象:向输入框添加一个向上键处理程序。当 keyup 被触发时,解决任何以前触发的仍然“待定”的 keyups。然后继续使用当前的 keyup 事件。在 keyup 事件本身内部,它根据输入值进行所有匹配,它始终检查当前事件是否仍在挂起,如果不是,它应该跳过该事件的其余部分。

问题似乎是,即使使用像 IE7 这样的慢速浏览器,每个 keyup 事件都会被阻塞。因此,如果用户输入“testing”,它会尝试在看到“te”的按键事件之前完成“t”字符的整个事件,依此类推。

那么问题就变成了,我怎样才能使 keyup 事件异步/非阻塞,或者这几乎是不可能的?

一个例子:

var search_values = new Array();
var deferred_searches = {};

function filterSearchResults(event) {
var input_element = jq(event.target);
var search_value = input_element.val();
console.log('user just typed final letter in :' + search_value);
for (var svi = 0; svi < search_values.length-1; svi++) {
if (deferred_searches[search_values[svi]] !== undefined &&
deferred_searches[search_values[svi]].state() == 'pending') {
console.log('resolving ' + search_values[svi])
deferred_searches[search_values[svi]].resolve(search_values[svi]);
}
}

var result_list = jq('div#header_project_selection_result_list');
var all_project_results = result_list.find('div.header_project_result');

console.log('beginning search for "'+search_value+'"');
if (search_value == '') {
// Blank input value means show all results
}
else {
// Non-blank value means search
if (! startSearchFilter(search_value, all_project_results)) {
return false; // this should return out of this current event handler
}
}
console.log('ending search for "'+search_value+'"');
},

/**
* Helper function that actually handles finding and hiding/showing results,
* and highlighting found text.
*
* Uses jQuery for this functionality.
*
* @param search_value string The text the user has input
* @param all_project_results jQuery A jQuery extended array of all project results to filter
*
* @return tbr boolean Flag indicating whether the search was short circuited
*/
function startSearchFilter(search_value, all_project_results) {
var tbr = true;

search_values.push(search_value);
deferred_searches[search_value] = jq.Deferred();
deferred_searches[search_value].done(function(sv) {
search_values = search_values.without(sv);
console.log('done deferred search for "'+sv+'" - disabling');
});

var number_of_results_found = 0;
var pr_count = all_project_results.length - 1;
var regexp = new RegExp(search_value, 'im');
for (var index = 0; index <= pr_count; index++) {
if (deferred_searches[search_value].state() == 'pending') {
// KEEP GOING
var ext_project_result = all_project_results.eq(index);
var result_data = ext_project_result.data();

//console.log(search_value+" is in state '"+deferred_searches[search_value].state()+"'.....' all_project_results.each() [inside]");
if (result_shown) {
number_of_results_found++;
// The input text has been found on data for the current project, so make sure we show that result row
ext_project_result.addClass('filtered');
}
else if (ext_project_result.hasClass('filtered')) {
// The input text has not been found, or the user is not an admin and can't view it, so hide that row
ext_project_result.removeClass('filtered');
}
continue; // keep going to the next result element
}
else {
tbr = false;
break; // break when short circuited
}
}
if (deferred_searches[search_value].state() == 'pending') {
deferred_searches[search_value].resolve(search_value); // explicitly resolve this finalized one
}

return tbr;
}

理论上这应该可行,但正如我提到的,它似乎总是阻塞。

最佳答案

而不是做你正在做的事情,你可能想看看一个叫做“去抖动”的概念,它基本上允许你创建一个可以多次调用但只有在没有被调用时才会完全执行的函数一定的时间。

(以下代码片段来自underscore.js)

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
var debounce = function(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
};
if (immediate && !timeout) {
func.apply(context, args);
}

clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
};

使用它,你可能会做这样的事情,它只会在用户停止输入后 500 毫秒执行我们昂贵的回调

$( "#searchbox" ).keyup( debounce(function() {
// Some expensive operation here
}, 500));

Ben Alman 提供了一个很好的插件(http://benalman.com/projects/jquery-throttle-debounce-plugin/),或者 LoDash/Underscore 提供了相同的功能,如果您正在使用它们的话。

关于javascript - 异步 keyup 事件/如何短路顺序 keyup 事件以提高速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12538344/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com