花潮论坛

搜索
热搜: 活动 交友 discuz
查看: 11|回复: 3

规避输入法编码上屏问题

[复制链接]
  • TA的每日心情
    奋斗
    2026-6-18 12:05
  • 签到天数: 1847 天

    [LV.Master]伴坛终老

    3256

    主题

    13万

    回帖

    28万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9

    花潮帅哥鼠牛虎兔龙蛇马羊猴鸡狗猪多彩人生星月交辉奔放热烈海样胸怀春风拂面火热情怀优雅迷人神秘浪漫相遇之美鹰傲苍穹花好月圆紫色情节飞龙在天王者至尊大将风范音画大师天籁妙音共看流星风雨同行我心永远幸福快乐喜乐安康侠骨柔肠心想事成开朗大方花潮管理

    发表于 2026-6-18 17:39 | 显示全部楼层 |阅读模式

    请马上登录,朋友们都在花潮里等着你哦:)

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x

    有些Web应用在触发诸如撤销、重做等机制过程中,凡涉及到中文输入法输入的内容,会在编辑器里呈现中文词条的输入法编码。以下案例虽然不是撤销重做,但也可以展现词条编码“上屏”的情形,案例中使用流行通用的防抖机制来限制输入文本的“上屏”操作,具体达成的是:用户的键盘输入会实时上屏,但连续的输入仅在两次输入之间间隔一秒,输入的内容才会“上屏”。点击“预览”进入效果演示页面,请尝试使用中文输入法输入任何文字(单字或词组都可以),故意让输入法候选词窗口停留一小段时间再选择输出的词条,此间会发现,“大屏”文本框里存在文字的输入法编码文本——

    <style>
        .tMid { text-align: center; margin: 20px; }
        #showbox { width: 600px; height: 200px; padding: 12px; }
        #inputbox { width: 300px; padding: 8px; }
    </style>
    
    <p class="tMid">
        <textarea id="showbox" value="" readonly></textarea>
    </p>
    <p class="tMid">
        <label for="inputbox" onclick="inputbox.value=''">请输入:</label>
        <input id="inputbox" type="text" value="" />
    </p>
    
    <script>
        // 防抖通用函数
        function debounce(func, delay) {
            let timer = null; // 定义定时器
            return function (...args) {
                clearTimeout(timer); // 清除之前的定时器
                timer = setTimeout(() => {
                    func.apply(this, args); // 延迟执行函数
                }, delay);
            };
        }
    
        // 输入内容搬到“大屏幕”
        inputbox.addEventListener('keyup', debounce((e) => {
            showbox.value += inputbox.value + '\n';
        }, 1000));
    </script>
        

    本文的任务就是避免上述案例展示的词条编码“上屏”现象的发生。

    这首先需要理解输入法上屏的基本工作流程,分为三个步骤:

    一、compositionstart(开始合成)

    以汉字“我”为例,其完整拼音输入法编码是 wo,当输入第一个字母 w,合成工作开始,这回触发 compositionstart 流程。

    JS compositionstart 事件

    compositionstart 事件是在用户开始使用文本合成系统,如输入法编辑器(IME)开始新的文本合成会话时触发的。例如,当用户使用拼音输入法开始输入汉字时,就会触发此事件。这个事件对于处理输入法中的文本输入尤为重要,因为它允许开发者在文本的合成过程开始时执行特定的逻辑。

    二、compositionupdate(合成更新)

    全拼输入“我”字,下一个字母是 o,这一部分的输入本质上实在更新编码的合成,触发编码的合成更新事件。

    JS compositionupdate 事件

    当文本合成系统(如输入法编辑器)控制的文本合成会话中接收到新字符时,会触发 compositionupdate 事件。该事件可能多次触发,例如输入“我们”, w之后的 omen这四个字母都会各自触发一次 compositionupdate 事件。

    三、compositionend(合成结束)

    拼音输入法输入环境下,通常文字的编码打完还不能上屏,需要按空格键或候选序号或以其它方式操作(如鼠标点击)才能让文字上屏;支持顶格上屏的输入法(例如五笔等)如果启用了顶格上屏机制则编码输入完毕会自动上屏。不论手动选择上屏还是自动上屏,上屏动作发生时会触发文本合成结束信息,触发 compositionend 事件。

    JS compositionend 事件

    当文本段落的组成完成或取消时,compositionend 事件将被触发 (具有特殊字符的触发,需要一系列键和其他输入,如语音识别或移动中的字词建议)。

    知道了输入法上屏的机制,我们就可以找到实现的方法。现在,将上述案例的代码修改如下,我们的目标就可以实现:

    <style>
        .tMid { text-align: center; margin: 20px; }
        #showbox { width: 600px; height: 200px; padding: 12px; }
        #inputbox { width: 300px; padding: 8px; }
    </style>
    
    <p class="tMid">
        <textarea id="showbox" value="" readonly></textarea>
    </p>
    <p class="tMid">
        <label for="inputbox" onclick="inputbox.value=''">请输入:</label>
        <input id="inputbox" type="text" value="" />
    </p>
    
    <script>
        let composing = false; // 合成状态标记
    
        function debounce(func, delay) {
            let timer = null; // 定义定时器
            return function (...args) {
                clearTimeout(timer); // 清除之前的定时器
                timer = setTimeout(() => {
                    func.apply(this, args); // 延迟执行函数
                }, delay);
            };
        }
    
        // 监听输入框键位输入 :内容搬到“大屏幕”
        inputbox.addEventListener('keyup', debounce((e) => {
            if (!composing) showbox.value += inputbox.value + '\n';
        }, 1000));
    
        // 监听输入框合成动作开始 : 正在合成,禁止上屏
        inputbox.addEventListener('compositionstart', () => composing = true);
    
        // 监听输入框合成动作结束 : 上屏
        inputbox.addEventListener('compositionend', () => composing = false);
    </script>
        

    核心:使用自定义的 composing 变量来记录输入法输入特定文字的合成态和完成态,开始时值为假(false),这样:其一,英文输入状态下输入的文本正常上大屏;其二,中文输入法状态下,监听 compositionstart(合成开始)事件,只要该事件被触发(开始输入汉字),合成态就存在( composing = true),此时会阻止上大屏的操作,同时监听 compositionend 事件,即,当输入法确定选词操作被触发时激活完成态,即令 composing = false,此时文本才可以上大屏。而 composing 变量必须作为一个开关作用于文本框的输入监听事件(详见案例二第 30 行代码的 if 语句,案例一对应语句即第 29 行代码中没有 if 条件判断)。

    评分

    参与人数 2威望 +80 金钱 +160 经验 +80 收起 理由
    红影 + 50 + 100 + 50 匠心独运,细节精致入微!
    梦江南 + 30 + 60 + 30 匠心独运,细节精致入微!

    查看全部评分

  • TA的每日心情
    开心
    2026-6-18 08:37
  • 签到天数: 754 天

    [LV.10]以坛为家III

    534

    主题

    2万

    回帖

    7万

    积分

    贵宾

    Rank: 7Rank: 7Rank: 7Rank: 7Rank: 7Rank: 7Rank: 7

    花潮美女鼠牛虎兔龙蛇马羊猴鸡狗猪缤纷心情心曲飞扬花好月圆飞龙在天音画大师天籁妙音共看流星风雨同行我心永远喜乐安康花潮贵宾

    发表于 2026-6-18 18:08 | 显示全部楼层
    谢谢黑黑老师辛苦,学习了。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2025-12-1 20:32
  • 签到天数: 1052 天

    [LV.10]以坛为家III

    1898

    主题

    33万

    回帖

    40万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9

    花潮美女虎龙狗猪多彩人生星月交辉海样胸怀火热情怀优雅迷人神秘浪漫缤纷心情草莓情怀蝴蝶情怀心曲飞扬星星情怀七彩绚丽活泼开朗女儿情怀相遇之美一往情深花好月圆心香一瓣紫色情节飞龙在天金剪刀天籁妙音妙笔生花风雨同行我心永远天长地久幸福快乐绚丽缤纷喜乐安康中秋征文周年庆指尖上的流年舞会之星分析(喊冤)章总结章杀人王小强章最佳杀刺临屏写诗七夕诗钟活动第五届风云第六届风云情人节花潮管理

    发表于 2026-6-18 19:24 | 显示全部楼层
    去试了一下,输入后需要停1秒就上屏了,如果一直输入就可以是很长一段文字。
     
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2025-12-1 20:32
  • 签到天数: 1052 天

    [LV.10]以坛为家III

    1898

    主题

    33万

    回帖

    40万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9

    花潮美女虎龙狗猪多彩人生星月交辉海样胸怀火热情怀优雅迷人神秘浪漫缤纷心情草莓情怀蝴蝶情怀心曲飞扬星星情怀七彩绚丽活泼开朗女儿情怀相遇之美一往情深花好月圆心香一瓣紫色情节飞龙在天金剪刀天籁妙音妙笔生花风雨同行我心永远天长地久幸福快乐绚丽缤纷喜乐安康中秋征文周年庆指尖上的流年舞会之星分析(喊冤)章总结章杀人王小强章最佳杀刺临屏写诗七夕诗钟活动第五届风云第六届风云情人节花潮管理

    发表于 2026-6-18 19:29 | 显示全部楼层
    不仅是输入的,复制过去的文字停1秒也能上屏呢。
    黑黑讲解辛苦了
     
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    小黑屋|手机版|Archiver|服务支持:DZ动力|huachaowang.com Inc. ( 蜀ICP备17032287号-1 )

    GMT+8, 2026-6-18 19:53 , Processed in 0.071687 second(s), 26 queries .

    Powered by Discuz! X3.4

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表