我有一些代碼可以在輸入欄位內的 keyup 上觸發一個函式。為了防止這個函式觸發每個文字鍵,我設定了一個半秒的超時函式,這樣我的代碼就不會發送垃圾郵件 ajax 請求。
但由于某種原因,這個超時代碼不起作用。
這是我最初擁有的,它確實有效:
形式:
<form class="search-address">
<input id="account_id" type="hidden" name="account_id" value="<?PHP echo $_SESSION['user']['id']; ?>">
<input class="search-word" type="text" placeholder="Zoeken in adresboek...">
</form>
我的觸發代碼:
$('.search-word').keyup(function(e) {
clearTimeout($.data(this, 'timer'));
if (e.keyCode == 13){
search(true);
}else{
$(this).data('timer', setTimeout(search, 500));
}
});
我的功能:
function search(force) {
var zoekwaarde = $(".search-word").val();
var account_id = $("#account_id").val();
$.ajax({
type:'post',
url:"includes/searchaddress.php",
data:({zoekwaarde: zoekwaarde, account_id: account_id}),
success:function(data){
$( "#adressenlist" ).show().empty().append( data );
$( "#deleteresult" ).hide();
$( "#adresresult" ).hide();
}
});
}
這有效,但問題是我有 2 個具有相同類的.search-word. 所以我稍微調整了我的代碼:
$('.search-word').keyup(function(e) {
searchword = $(this).val();
clearTimeout($.data(this, 'timer'));
if (e.keyCode == 13){
search(true, searchword);
}else{
$(this).data('timer', setTimeout(search(true, searchword), 500));
}
});
function search(force, searchword) {
var zoekwaarde = searchword;
var account_id = $("#account_id").val();
$.ajax({
type:'post',
url:"includes/searchaddress.php",
data:({zoekwaarde: zoekwaarde, account_id: account_id}),
success:function(data){
$( "#adressenlist" ).show().empty().append( data );
$( "#deleteresult" ).hide();
$( "#adresresult" ).hide();
}
});
}
我使用searchword = $(this).val();所以我只發布$(this)輸入欄位的值,而不是 dom 樹中的最后一個。我認為這會奏效,但這會破壞我的超時功能,現在它會search在每次按鍵時立即觸發該功能。我能做些什么來解決這個問題?
uj5u.com熱心網友回復:
嘗試將您的搜索功能包裝在一個匿名函式(回呼)中,例如:
setTimeout(() => { search(param1, param2) }, 1500)
uj5u.com熱心網友回復:
OP 需要創建事件處理程式的節流版本。
例如下劃線和lodash都提供了一種throttle方法。
function handleSearch(/*evt*/) {
console.log('handleSearch :: this.value ...', this.value);
}
document
.forms[0]
.querySelector('[type="search"]')
.addEventListener('input', handleSearch);
const elmSearch = document
.forms[1]
.querySelector('[type="search"]');
// - with underscore's `throttle` the handler's `event` argument
// unfortunately gets lost/ommitted.
// - a viable workaround is to firstly bind the to be handled control
// to `handleSearch` and then to create a throttled handler from it.
elmSearch.addEventListener('input', _.throttle(handleSearch.bind(elmSearch), 500));
[type=search] { width: 17em; margin: 10px 0; }
<script src="https://cdn.jsdelivr.net/npm/[email protected]/underscore-umd-min.js"></script>
<form class="search-address">
<input type="search" placeholder="immediate addressbook search ...">
</form>
<form class="search-address">
<input type="search" placeholder="throttled addressbook search ...">
</form>
編輯
“所以......他們應該完全重寫他們的代碼,洗掉 jQuery,但添加下劃線?對于這樣一個簡單的問題來說似乎有點太多了。——Hertic Monkey”
“@HereticMonkey ......沒有人阻止他們撰寫自己的
throttle抽象,無論如何我都會建議。上面的例子是一個歸結為最必要的用例,以證明差異。OP 有 2k 的聲譽。我認為 OP 可以應付這種情況。 – Peter Seliger”
由于Heretic Monkey的論點,有一個自定義throttle實作可以降低 OP 事件處理腳本的復雜性。然后可以將 OP 的代碼重構為類似于以下示例的內容...
function search(force, searchword) {
var zoekwaarde = searchword;
var account_id = $("#account_id").val();
$.ajax({
type: 'post',
url: "includes/searchaddress.php",
data: ({zoekwaarde: zoekwaarde, account_id: account_id}),
success: function(data){
$( "#adressenlist" ).show().empty().append( data );
$( "#deleteresult" ).hide();
$( "#adresresult" ).hide();
}
});
}
function handleSearch() {
const searchword = this.value;
// search(true, searchword)
console.log(`search(true, ${ searchword })`);
}
$('.search-word').on('input', throttle(handleSearch, 500));
body { margin : 0; }
[type=search] { width: 17em; margin-bottom: 3px; }
.as-console-wrapper { min-height: 70%!important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="search-address">
<input type="hidden" name="account_id" id="account_id" value="sessionUserId" />
<input type="search" placeholder="Zoeken in adresboek ..." class="search-word" />
</form>
<form class="search-another-address">
<input type="hidden" name="account_id" id="account_id" value="sessionUserId" />
<input type="search" placeholder="Zoeken in adresboek ..." class="search-word" />
</form>
<script>
function isFunction(type) {
return (
(typeof type === 'function')
&& (typeof type.call === 'function')
&& (typeof type.apply === 'function')
);
}
function getSanitizedTarget(target) {
return target ?? null;
}
function getSanitizedInteger(value) {
return (Number.isSafeInteger(value = parseInt(value, 10)) && value) || 0;
}
function getSanitizedPositiveInteger(value) {
return Math.max(getSanitizedInteger(value), 0);
}
function throttle(proceed, threshold, isSuppressTrailingCall, target) {
if (!isFunction(proceed)) {
return proceed;
}
target = getSanitizedTarget(target);
threshold = getSanitizedPositiveInteger(threshold) || 200;
isSuppressTrailingCall = !!isSuppressTrailingCall;
let timeoutId, timeGap;
let timestampRecent, timestampCurrent;
let context, argsArray;
function trigger() {
timestampRecent = timestampCurrent;
proceed.apply(context, argsArray);
}
function throttled() {
clearTimeout(timeoutId);
context = target ?? getSanitizedTarget(this);
argsArray = [...arguments];
timestampCurrent = Date.now();
if (timestampRecent) {
timeGap = (timestampCurrent - timestampRecent);
if (isSuppressTrailingCall && (timeGap >= threshold)) {
// trailing call will be suppressed.
trigger();
} else {
timeoutId = setTimeout(trigger, Math.max((threshold - timeGap), 0));
}
} else {
// initial call.
trigger();
}
}
return throttled;
}
</script>
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/345112.html
標籤:javascript html 查询
下一篇:等待API呼叫結果和更新串列組件
