摘要:在JavaScript中,compositionstart 和 compositionend 事件是用于处理输入法输入的两个重要事件。虽然在日常开发中可能不常用到它们,但对于处理中文、日文等复杂输入法的...
在JavaScript中,compositionstart 和 compositionend 事件是用于处理输入法输入的两个重要事件。虽然在日常开发中可能不常用到它们,但对于处理中文、日文等复杂输入法的应用来说,这两个事件是至关重要的。
什么是compositionstart和compositionend事件?
compositionstart事件在用户开始使用输入法输入文本时触发,而compositionend事件则在输入法输入结束时触发。这两个事件通常与文本框或文本区域的输入事件结合使用,以便在用户正在输入文字时进行相应的处理。
为什么需要处理compositionstart和compositionend事件?
在处理中文等复杂输入时,通常用户并不是一次性输入完整的文字,而是在输入过程中逐步构建文字。例如,在使用中文输入法时,用户可能会先输入一个词的拼音,然后根据提示选择合适的文字。在这个过程中,输入法会通过compositionstart和compositionend事件来通知应用程序正在进行输入。
如何使用compositionstart和compositionend事件?
下面是一个简单的例子,演示了如何使用 compositionstart 和 compositionend 事件处理中文输入:
var inputElement = document.getElementById('input');
inputElement.addEventListener('compositionstart', function(event) {
// 在输入法开始输入时执行的操作
console.log('开始输入文字');
});
inputElement.addEventListener('compositionend', function(event) {
// 在输入法输入结束时执行的操作
console.log('输入结束');
// 这里可以获取到最终的输入文字,然后进行相应的处理
console.log('输入的文字:', event.data);
});在这个例子中,当用户开始输入文字时,会触发compositionstart事件,我们可以在这个事件的处理函数中执行一些预处理操作。当用户输入结束时,会触发compositionend事件,我们可以在这个事件的处理函数中获取最终的输入文字,并进行相应的处理。
compositionstart和compositionend的应用场景
现在有一个这样的需求:当用户输入相关文字时,对下面的列表进行搜索,现在的代码是这样的:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<input type="text" name="search" id="search">
<ul id="lists">
<li><a href="#">列表</a></li>
<li><a href="#">新增</a></li>
<li><a href="#">修改</a></li>
<li><a href="#">删除</a></li>
</ul>
<script>
$(document).ready(function() {
$('#search').on('input', function(event) {
var searchText = $(this).val().toLowerCase();
$('#lists li').each(function() {
var linkText = $(this).text().toLowerCase();
if (linkText.includes(searchText)) {
$(this).show();
} else {
$(this).hide();
}
});
});
});
</script>
</body>
</html>代码看上去没有问题,但是当输入中文时,一个中文字符没有打完,已经对下面文字进行了检索,而且已经没有列表文字了,当我们输入完成中文后,列表的文字又出来了,这显然不是我们所期望的结果。

这时 CompositionStart 和 CompositionEnd 事件就能派上用场,以下是修改后的代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<input type="text" name="search" id="search">
<ul id="lists">
<li><a href="#">列表</a></li>
<li><a href="#">新增</a></li>
<li><a href="#">修改</a></li>
<li><a href="#">删除</a></li>
</ul>
<script>
$(document).ready(function() {
var composing = false; // 是否处于中文输入法的输入状态
$('#search').on('input', function(event) {
if (!composing) {
var searchText = $(this).val().toLowerCase();
$('#lists li').each(function() {
var linkText = $(this).text().toLowerCase();
if (linkText.includes(searchText)) {
$(this).show();
} else {
$(this).hide();
}
});
}
});
$('#search').on('compositionstart', function(event) {
composing = true; // 中文输入法输入开始
});
$('#search').on('compositionend', function(event) {
composing = false; // 中文输入法输入结束
$(this).trigger('input'); // 触发input事件进行搜索
});
});
</script>
</body>
</html>
