合成事件在san.js中的应用

一、 什么是合成事件

DOM3 Event 新增了合成事件(CompositionEvent ), 用于处理通常使用 IME 输入时的复杂输入序列。

二、合成事件常见事件

  1. compositionstart:文本合成系统如 IME(即输入法编辑器)开始新的输入合成时会触发 compositionstart 事件。
  2. compositionupdate :事件触发于字符被输入到一段文字的时候
  3. compositionend:当文本段落的组成完成或取消时,compositionend 事件将被触发

合成事件在很多方面与输入事件很类似。在合成事件触发时,事件目标是接收文本的输入字段。唯
一增加的事件属性是 data,其中包含的值视情况而异:

  • 在 compositionstart 事件中,包含正在编辑的文本(例如,已经选择了文本但还没替换);
  • 在 compositionupdate 事件中,包含要插入的新字符;
  • 在 compositionend 事件中,包含本次合成过程中输入的全部内容。

与文本事件类似,合成事件可以用来在必要时过滤输入内容。可以像下面这样使用合成事件:

<input id="myText" type="text"/><script>![请添加图片描述](https://img-blog.csdnimg.cn/481e6c9238ad45dcaabedfb9adcbff26.png)let textbox = document.getElementById("myText");textbox.addEventListener("compositionstart", (event) => {console.log('compositionstart', event.data);});textbox.addEventListener("compositionupdate", (event) => {console.log('compositionupdate', event.data);});textbox.addEventListener("compositionend", (event) => {console.log('compositionend', event.data);});</script>

请添加图片描述

三、合成事件的使用场景

需求背景:根据input输入的文字进行列表过滤。
需求实现

<template><div class="kh-idx"><input v-model="inputVal" type="text" /><ul class="kh-idx-ul"><li v-for="item in filteredList" :key="item" class="kh-idx-li">{{ item }}</li></ul></div>
</template><script lang="ts">
import { defineComponent, ref } from 'vue';export default defineComponent({name: 'KhIndex',setup() {return {inputVal: ref(''),list: ref(['爱与希望','花海','Mojito','最长的电影','爷爷泡的茶'])}},computed: {filteredList() {if (!this.inputVal) {return this.list;}return this.list.filter(item => item.indexOf(this.inputVal) > -1);}},
});
</script><style lang="less" scoped>
/** define kh-idx */
.kh-idx {&-ul {padding: 15px 8px;border: 1px solid #9c27b0;}&-li {padding: 4px 2px;border: 1px solid gainsboro;}
}
</style>

虽然能实现该功能,但是在使用中文进行输入时会有拼音到字符转变的时间,这段时间是没有办法实现过滤的。效果如下
请添加图片描述
为了优化该场景,可以使用compositionstart和compositionend相关事件进行优化。代码如下

<template><div class="kh-idx"><input v-model="inputVal"type="text"@compositionupdate="handleCompositionUpdate"@compositionend="handleCompositionEnd"/><ul class="kh-idx-ul"><li v-for="item in filteredList" :key="item" class="kh-idx-li">{{ item }}</li></ul></div>
</template><script lang="ts">
import { defineComponent, ref } from 'vue';export default defineComponent({name: 'KhIndex',setup() {let inputVal = ref('');const handleCompositionUpdate = (e: CompositionEvent) => {console.log('handleCompositionUpdate', e.data);inputVal.value = e.data;};const handleCompositionEnd = (e: CompositionEvent) => {console.log('handleCompositionEnd', e.data);inputVal.value = e.data;};return {inputVal,list: ref(['爱与希望','花海','Mojito','最长的电影','爷爷泡的茶']),handleCompositionUpdate,handleCompositionEnd}},computed: {filteredList() {if (!this.inputVal) {return this.list;}return this.list.filter(item => item.indexOf(this.inputVal) > -1);}},
});
</script><style lang="less" scoped>
/** define kh-idx */
.kh-idx {&-ul {padding: 15px 8px;border: 1px solid #9c27b0;}&-li {padding: 4px 2px;border: 1px solid gainsboro;}
}
</style>

请添加图片描述
请添加图片描述

四、san.js 中合成事件的应用

function elementOwnAttached() {if (this._rootNode) {return;}var isComponent = this.nodeType === NodeType.CMPT;var data = isComponent ? this.data : this.scope;/* eslint-disable no-redeclare */// 处理自身变化时双向绑定的逻辑var xProps = this.aNode._xp;for (var i = 0, l = xProps.length; i < l; i++) {var xProp = xProps[i];switch (xProp.name) {case 'value':switch (this.tagName) {case 'input':case 'textarea':if (isBrowser && window.CompositionEvent) {elementOnEl(this, 'change', inputOnCompositionEnd);elementOnEl(this, 'compositionstart', inputOnCompositionStart);elementOnEl(this, 'compositionend', inputOnCompositionEnd);}// #[begin] allua/* istanbul ignore else */if ('oninput' in this.el) {// #[end]elementOnEl(this, 'input', getInputXPropOutputer(this, xProp, data));// #[begin] allua}else {elementOnEl(this, 'focusin', getInputFocusXPropHandler(this, xProp, data));elementOnEl(this, 'focusout', getInputBlurXPropHandler(this));}// #[end]break;case 'select':elementOnEl(this, 'change', getXPropOutputer(this, xProp, data));break;}break;case 'checked':switch (this.tagName) {case 'input':switch (this.el.type) {case 'checkbox':case 'radio':elementOnEl(this, 'click', getXPropOutputer(this, xProp, data));}}break;}}var owner = isComponent ? this : this.owner;for (var i = 0, l = this.aNode.events.length; i < l; i++) {var eventBind = this.aNode.events[i];// #[begin] errorwarnEventListenMethod(eventBind, owner);// #[end]elementOnEl(this, eventBind.name,getEventListener(eventBind, owner, data, eventBind.modifier),eventBind.modifier.capture);}if (isComponent && this.nativeEvents) {for (var i = 0, l = this.nativeEvents.length; i < l; i++) {var eventBind = this.nativeEvents[i];// #[begin] errorwarnEventListenMethod(eventBind, this.owner);// #[end]elementOnEl(this, eventBind.name,getEventListener(eventBind, this.owner, this.scope),eventBind.modifier.capture);}}var transition = elementGetTransition(this);if (transition && transition.enter) {try {transition.enter(this.el, empty);}catch (e) {handleError(e, isComponent ? owner.parentComponent : owner, 'transitionEnter');}}
}

在上面的代码中,san对input 双向数据绑定时,监听了compositionstart和compositionend事件,然后两个事件处理函数也不是很麻烦,如下

/*** 双绑输入框CompositionEnd事件监听函数** @inner*/
function inputOnCompositionEnd() {if (!this.composing) { // 只有 composing 不为 1 时,后续才不执行return;}this.composing = 0;trigger(this, 'input'); // 触发 input 事件,trigger 函数中是自定义的 input 事件,这样用于定义的input事件就得意执行
}/*** 双绑输入框CompositionStart事件监听函数** @inner*/
function inputOnCompositionStart() {this.composing = 1; // composing 为 1 表示正在合成(composing)
}/*** 触发元素事件** @inner* @param {HTMLElement} el DOM元素* @param {string} eventName 事件名*/
function trigger(el, eventName) {var event = document.createEvent('HTMLEvents');event.initEvent(eventName, true, true);el.dispatchEvent(event); // 触发自定义事件
}

这样san就解决了使用input事件时,在输入汉字中没有出发input事件的情况。效果如下
请添加图片描述
参考文章

  1. js中compositionstart和compositionend事件
  2. javascript 高级程序设计(第四版)
  3. CompositionEvent

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/191441.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SUID提权教程

SUID提权方法 一、SUID是什么&#xff1f;二、如何设置SUID权限&#xff1f;三、已知的具有SUID权限的二进制可执行文件四、查找具有root权限的SUID的文件1.find命令提权2.nmap命令提权3.more命令提权4.less命令提权5.bash命令提权6.vim命令提权7.awk命令提权8.cp命令提权 五、…

springcloudalibaba-3

一、Nacos Config入门 1. 搭建nacos环境【使用现有的nacos环境即可】 使用之前的即可 2. 在微服务中引入nacos的依赖 <!-- nacos配置依赖 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-…

【动态规划】求解编辑距离问题

目录 问题描述递推关系运行实例时空复杂度优化Hirschberg 算法 问题描述 编辑距离问题是求解将⼀个字符串转换为另⼀个字符串所需的插⼊、删除、替换的最小次数。 C O M M O M → s u b C O M M U M → s u b C O M M U N → i n s C O M M U N E \mathbb{COMMOM} \overset{sub…

HarmonyOS真机调试报错:INSTALL_PARSE_FAILED_USESDK_ERROR处理

1、 新建应用时选择与自己真机匹配的sdk版本 查看自己设备sdk版本 创建时先择匹配版本&#xff1a; 2、 根据报错提示连接打开处理方案 3、查询真机版本对应的compileSdkVersion 和 compatibleSdkVersion 提示3.1版本之后和3.1版本之前的不同命令&#xff08;此处为3.0版…

Scrum框架中的Sprint

上图就是sprint里要做的事。Sprint是scrum框架的核心&#xff0c;是所有的想法、主意转换为价值的地方。所有实现产品目标的必要工作都在sprint里完成&#xff0c;这些工作主要包括Sprint 计划&#xff08;Sprint planning&#xff09;、每日站会&#xff08;Daily Scrum&#…

异地工业设备集中运维、数据采集,一招搞定

为了提升运维效率&#xff0c;能够及时发现和响应设备的故障、异常和潜在问题。 越来越多的企业都在搭建“集中式”的远程智慧运维体系&#xff0c;以提高运维效率和降低成本。 异地工业设备远程运维&#xff0c;提升响应效率、降低运维成本 以国内陕西某机床公司为例&#xff…

vue+element实现多级表头加树结构

标题两种展示方式 方式一 完整代码: <template><div class"box"><el-tableref"areaPointTable":data"tableData"border:span-method"objectSpanMethod":header-cell-style"tableHeaderMerge"><el-ta…

【10套模拟】【6】

关键字&#xff1a; 有向图入度、无向图度、一次深度优先、快速排序平均性能、折半查找、判断是否是二叉排序树、链式直接入插入排序

现在的各类解释非常混乱,到底什么是智慧城市?

智慧城市&#xff0c;简单来说&#xff0c;就是运用先进的信息和通信技术&#xff0c;让城市管理更加智能、高效&#xff0c;让市民的生活更加便捷、舒适。 在我们日常生活中&#xff0c;智慧城市带来的改变无处不在。 想象一下&#xff0c;当你早上醒来&#xff0c;你的手机已…

腾讯云新用户优惠活动有哪些可以参加?腾讯云新人服务器优惠活动

腾讯云作为国内领先的云服务提供商&#xff0c;不仅为用户提供稳定可靠的云服务器&#xff0c;还为新用户带来了一系列的优惠活动和代金券&#xff0c;以降低购买成本&#xff0c;提高业务效益。在这里&#xff0c;我们将为您详细介绍腾讯云服务器的新人优惠活动及代金券&#…

vue3+vant 实现树状多选组件

vue3vant 实现树状多选组件 需求描述效果图代码父组件引用selectTree组件 tree组件数据格式 需求描述 移动端需要复刻Pc端如上图的功能组件&#xff0c;但vant无组件可用&#xff0c;所以自己封装一个。 效果图 代码 父组件引用 import TreeSelect from "/selectTree.vu…

​软考-高级-系统架构设计师教程(清华第2版)【第17章 通信系统架构设计理论与实践(P614~646)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第17章 通信系统架构设计理论与实践&#xff08;P614~646&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图