Keyup 功能仅对输入的第一个字母起作用
Keyup function is only working once for first letter of input
我有一个文本输入框,用户可以在其中输入所需的页面名称
<input type='text' id='pageName' name='PageName' class='form-control pageName'>
我正在尝试使用 keyup 函数来触发 Ajax 以检查页面是否存在,但是当键入类似 index
的内容时 Ajax 仅发送 I
(第一个字母)而不是 运行。
脚本:
<script>
$("#pageName").keyup(function() {
$.ajax({
type: "GET",
async: false,
url: "CheckPageName.php",
data: {
'PageName': jQuery(this).val()
},
cache: false,
success: function(html) {
$("#NotAllowed").replaceWith(html);
$('#loader_image').hide();
}
});
});
</script>
如果我添加 console.log(html);
它会在日志中正确显示值,但 $("#NotAllowed").replaceWith(data);
仅显示第一个字母或 2(如果我键入速度快!)
我错过了什么?
您应该将 keyup 函数包装在 debounce 中。当从服务器请求数据时,这将节省您一些时间和负载。
const debounce = (callback, wait) => {
let timeoutId = null;
return (...args) => {
const [ { target } ] = args;
window.clearTimeout(timeoutId);
timeoutId = window.setTimeout(() => {
callback.apply(target, args);
}, wait);
};
}
const handleKeyUp = debounce(function() {
$('#loader-image').show();
$.ajax({
type: 'GET',
async: false,
url: 'CheckPageName.php',
data: { 'PageName': $(this).val() },
cache: false,
success: function(data, textStatus, jqXHR) {
$('#not-allowed').html(data);
$('#loader-image').hide();
},
error: function(jqXHR, textStatus, errorThrown) {
$('#not-allowed').html('<p>Not found...</p>');
// Hide the mask after 1 second, to mimic waiting for a response
// Remove this timeout once the response is hooked-up
setTimeout(function() {
$('#loader-image').hide();
}, 1000);
}
});
}, 250); // Search only after 250ms once typing has stopped
$('#loader-image').hide();
$('#page-name').on('keyup', handleKeyUp);
#loader-image {
display: flex;
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
margin: 0;
padding: 0;
z-index: 999;
background: rgba(0, 0, 0, 0.5);
justify-content: center;
align-items: center;
font-weight: bold;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<div class="container">
<form>
<div class="mb-3">
<label for="page-name" class="form-label">Search existing page name</label>
<input type="text" id="page-name" name="page-name" class="form-control">
<div id="page-name-help" class="form-text">Check for an existing page.</div>
</div>
</form>
<hr />
<div id="not-allowed"></div>
</div>
<div id="loader-image">Loading...</div>
此问题与您的 AJAX 调用无关(尽管 async:false
仍然是不必要的,并且通常是不好的做法)。
问题在于 jQuery replaceWith 函数的作用。根据文档,它删除了它匹配的元素,并将整个元素替换为您提供给函数的内容。请注意,它替换了 整个元素,而不仅仅是其内部内容!
所以它只工作一次的原因很简单,因为在第一次执行后,“NotAllowed”元素不再存在 - replaceWith 已删除它并用您的 AJAX 请求的响应替换它!
如果你想更新一个元素的内容而不删除它,在jQuery中你可以使用.html()
或.text()
(取决于内容是否是HTML 或纯文本)。在这种情况下 .text()
就可以了:
success: function(response) {
$("#NotAllowed").text(response);
$('#loader_image').hide();
}
我有一个文本输入框,用户可以在其中输入所需的页面名称
<input type='text' id='pageName' name='PageName' class='form-control pageName'>
我正在尝试使用 keyup 函数来触发 Ajax 以检查页面是否存在,但是当键入类似 index
的内容时 Ajax 仅发送 I
(第一个字母)而不是 运行。
脚本:
<script>
$("#pageName").keyup(function() {
$.ajax({
type: "GET",
async: false,
url: "CheckPageName.php",
data: {
'PageName': jQuery(this).val()
},
cache: false,
success: function(html) {
$("#NotAllowed").replaceWith(html);
$('#loader_image').hide();
}
});
});
</script>
如果我添加 console.log(html);
它会在日志中正确显示值,但 $("#NotAllowed").replaceWith(data);
仅显示第一个字母或 2(如果我键入速度快!)
我错过了什么?
您应该将 keyup 函数包装在 debounce 中。当从服务器请求数据时,这将节省您一些时间和负载。
const debounce = (callback, wait) => {
let timeoutId = null;
return (...args) => {
const [ { target } ] = args;
window.clearTimeout(timeoutId);
timeoutId = window.setTimeout(() => {
callback.apply(target, args);
}, wait);
};
}
const handleKeyUp = debounce(function() {
$('#loader-image').show();
$.ajax({
type: 'GET',
async: false,
url: 'CheckPageName.php',
data: { 'PageName': $(this).val() },
cache: false,
success: function(data, textStatus, jqXHR) {
$('#not-allowed').html(data);
$('#loader-image').hide();
},
error: function(jqXHR, textStatus, errorThrown) {
$('#not-allowed').html('<p>Not found...</p>');
// Hide the mask after 1 second, to mimic waiting for a response
// Remove this timeout once the response is hooked-up
setTimeout(function() {
$('#loader-image').hide();
}, 1000);
}
});
}, 250); // Search only after 250ms once typing has stopped
$('#loader-image').hide();
$('#page-name').on('keyup', handleKeyUp);
#loader-image {
display: flex;
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
margin: 0;
padding: 0;
z-index: 999;
background: rgba(0, 0, 0, 0.5);
justify-content: center;
align-items: center;
font-weight: bold;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<div class="container">
<form>
<div class="mb-3">
<label for="page-name" class="form-label">Search existing page name</label>
<input type="text" id="page-name" name="page-name" class="form-control">
<div id="page-name-help" class="form-text">Check for an existing page.</div>
</div>
</form>
<hr />
<div id="not-allowed"></div>
</div>
<div id="loader-image">Loading...</div>
此问题与您的 AJAX 调用无关(尽管 async:false
仍然是不必要的,并且通常是不好的做法)。
问题在于 jQuery replaceWith 函数的作用。根据文档,它删除了它匹配的元素,并将整个元素替换为您提供给函数的内容。请注意,它替换了 整个元素,而不仅仅是其内部内容!
所以它只工作一次的原因很简单,因为在第一次执行后,“NotAllowed”元素不再存在 - replaceWith 已删除它并用您的 AJAX 请求的响应替换它!
如果你想更新一个元素的内容而不删除它,在jQuery中你可以使用.html()
或.text()
(取决于内容是否是HTML 或纯文本)。在这种情况下 .text()
就可以了:
success: function(response) {
$("#NotAllowed").text(response);
$('#loader_image').hide();
}