最近把朋友做一个英文单词前缀搜索的查询网页,据说是某些英文考试中经常出现给出前缀填写后面的剩余字母的完形填空,为了方便大家解题,搞了个简单的网站。
英文这个网页的输入框比较特殊,需要重新自定义一个输入框,为了方便起见,我决定在原生输入框下面写样式,而原生输入框设置为透明即可,这样可以复用输入框的onchaneg、value等属性。
我自定义了一个光标在输入框中小方块的后面,每次输入的输入的时候,光标定位到最后,和正常输入一样操作。
但还是遇到了问题,光标在首次聚焦的时候,有可能会定位到最前面,这样用户打字的时候,其实是输入到了st的前面,不符合预期;另外,在输入框中不小心双击的时候,其实是会选中整个输入框里的文字,这样再打字的话,原来所有的输入会被替换成一个字母,不符合预期。就怎么一个小问题,花了我一两小时来解决。
最终找到的办法是使用HTMLInputElement.setSelectionRange()
函数,可以在MDN 查看详细介绍。这个函数的主要作用是,用js 选中一段文本,前两个参数是start,end。设置之后可以选中dom 元素中的文本。查资料发现,如果start==end 这选中的文本长度为0,实质上是把光标位置挪到了start 位置。
考虑到光标聚焦、挪动、双击等,其实都有点击操作,所以我决定在每次点击操作之后挪动光标到最后,这样就能解决问题。
//解决光标一直定位到最后 handleClick=(e)=>{ const input = e.target setTimeout(()=>{ input.setSelectionRange(100,100) },0) }
其中设置pos=100,是懒得计算最后的长度,实测发现,只要设置的值超过最大值,那么光标会定位到最后,其实前端中有很多地方都可以采用设置一个超大的值来简化计算。
采用setTimeout异步操作,是考虑到点击、聚焦等浏览器事件,有很多默认行为,为了让我们的操作不干扰默认操作,或者不被默认操作覆盖导致无效,我们进行异步操作,等待流量的行为执行完毕后,在挪到光标,对于用户是无感知的,不影响体验。
最后,贴上朋友的网址,大家可以去体验一下:http://www.duolink.net/
参考文档:
* https://www.jianshu.com/p/d89855e5db28
* https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLInputElement/setSelectionRange