如何获取Input中光标的位置?
一、背景
测试提出气泡要能跟随光标的位置移动
二、气泡方案
旧方案
input 上波浪线由覆盖在 input 上面的 span 显示,span 绑定点击事件,显示对应的气泡。
问题:
- 点击 span 后光标在 input 中的位置需要额外计算,容易出错
- 无法拖动选中
新方案
- 波浪线方案保持一致,但不覆盖
input
,只作为样式存在,不关心事件 - 使用
input
特有的属性selectionStart
,兼容性表现也很好 - 复用波浪线的位置数据,代替通过 span 的点击事件确定位置
三、实现
确定了新方案之后,主要的问题就变成了解决如何获取光标所在的位置。
想要获取光标相对于屏幕的位置信息,大概可以分三步走:
input
相对于屏幕的位置- 光标相对于
input
的位置 - 累加位置信息的得出光标相对屏幕的位置
难点主要在第二步,如何获取光标相对于屏幕的位置。
其实我们反过来想一下,获取光标位置 ≈ 获取光标后面的元素的位置信息(为什么是 ≈,后面会解释)
这个过程大概也可以分为三步走
- mock 出一个于
input
一模一样DOM
- 根据
selectionStart
的信息把input
文字分为两部分 - 获取后一部分的元素的位置信息即为光标相对于
input
的位置
有了思路之后,就可以着手实现了:
- 为了方便可以直接获取
getComputedStyle().cssText
,作为mock input
的style
,当然最好是获取和位置相关的css
就好。 mock
两个dom
,储存input
的文字信息。- 根据
selectionStart
把input
截断为两段,像这样:
最后就可以通过 offset
来获取位置信息
1 | { |
四、问题
对于这种情况,1,2 的位置 selectionStart 是一样的,按照我们上面的方法,我们只能获取到 2 的位置信息。这也是目前没有解决的问题之一(也是 ≈ 的原因)。
大家有什么好的方案欢迎提出探讨。
不对之处欢迎指正,附上 demo 地址:codepen
相关资料: