中文输入法中光标跟随能力触发的浏览器事件探究

本文探讨了在模拟中文输入法光标跟随过程中遇到的挑战,包括监听键盘事件、判断光标位置、性能优化及兼容性处理。通过分析浏览器的输入监听机制,发现可以利用 事件在间接输入时捕获光标移动,但考虑到性能,最后采用键盘事件结合用户按键输入判断来优化光标跟随的触发时机。同时,文章也提到了在不同输入法和浏览器中的兼容性问题以及兜底方案。
摘要由CSDN通过智能技术生成

:::tip 最近在着手腾讯文档的输入体验优化,在其中有一个不起眼的小需求引起了我的注意,并顺便研究了一些事件监听机制相结合的特点,特此记录一下填坑过程。 :::

模拟光标跟随

大部分的主流输入法都有这样一个特性,在输入中文时,可以通过左右方向键控制光标,移动至输入区中任意两个字符之间的位置,用户接下来的字符输入将在光标处直接插入。

由于腾讯文档的渲染的画布是完全自主实现的,为了在体验上与普通可编辑画布保持一致,我们需要自己来模拟这一光标的移动行为。

首先,我们需要确定的是输入法中的模拟光标进行更新的时机。经试验,用户在进行中文输入时,若使用了方向键移动光标,将会触发光标的移动行为。因此,首先要解决的是使用合适的事件监听来捕获这一行为,从而进行更新。既然是对输入框的行为进行模拟,自然而然的,我们首先想到的是输入框触发的监听器。

浏览器输入框对输入的监听机制

在浏览器对键盘的输入规范中,将键盘输入分为了直接输入与间接输入两种。直接输入将会触发输入框的 onInput 事件 (IE9 之前不支持该事件,只能用 onKeyUp 等键盘事件作为降级选择)。而对于间接输入,规范将事件监听分为了 onCompositionStart, onCompositionUpdate, onCompositionEnd 三个部分。

而间接输入的同时,中间态的写入也会导致输入框内容的变化,从而也会触发 onInput 事件。因此在间接输入中,事件的触发次序为:

问题描述: 在Linux下运行javaswing程序时,中文输入法下输入时,光标不会随着输入移动,会停留在原位置。 问题分析: 这是Linux系统下中文输入法的默认行为,由于输入法引擎和Java GUI的事件处理机制不同,在输入时会出现光标不跟随的现象。 解决方案: 可以通过在程序监听键盘事件,并手动更新光标位置来解决这个问题。下面是一个示例代码: ``` import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Point; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.im.InputContext; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; public class InputMethodCursor extends JFrame implements KeyListener { /** * */ private static final long serialVersionUID = 1L; JTextArea inputArea; JPanel panel; public InputMethodCursor() { setTitle("Input Method Cursor"); setSize(new Dimension(400, 400)); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); inputArea = new JTextArea(); inputArea.setPreferredSize(new Dimension(300, 300)); inputArea.setWrapStyleWord(true); inputArea.setLineWrap(true); inputArea.addKeyListener(this); JScrollPane scrollPane = new JScrollPane(inputArea); panel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.anchor = GridBagConstraints.NORTHWEST; panel.add(scrollPane, gbc); getContentPane().setLayout(new BorderLayout()); getContentPane().add(panel, BorderLayout.CENTER); setVisible(true); } @Override public void keyPressed(KeyEvent e) { if (InputContext.getInstance().getLocale().equals("zh_CN")) { Point point = inputArea.getCaretPosition(); inputArea.setText(inputArea.getText() + e.getKeyChar()); inputArea.setCaretPosition(point.x + 1); } } @Override public void keyReleased(KeyEvent arg0) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent arg0) { // TODO Auto-generated method stub } public static void main(String[] args) { new InputMethodCursor(); } } ``` 在输入法为文时,监听键盘事件,获取当前光标位置并手动更新位置。 这样就可以在Linux系统上正常使用中文输入法了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值