模仿微信@效果

有接到需求,需要做一个输入#号,弹出下拉框,进行选择并替换到里面的内容。如下图,支持联想。做的不好,还望提出意见。

效果如图   

可能的情况


1.用户顺序输入#号,然后弹出下拉框。

2.用户左右键移动,再输入#号弹出下拉框。

3.用户鼠标点击某个位置在输入#号,弹出下拉框。

等等

思路


最简单的方法 -- jquery-UI 封装的 Autocomplete() 方法,谁用谁知道,好用!

自己实现


项目中使用vue作为技术栈,交互还是比较方便的。

这里需要了解一下几个知识:

1.window.getSelection() 方法对当前激活选中去(文本高亮处)进行操作。移步JavaScript标准Selection操作 - Rain Man - 博客园

2.可输入div,div的属性 contenteditable,请移步 vue2 实现 div contenteditable="true" 类似于 v-model 的效果 - acco - SegmentFault 思否

3.dom.getBoundingClientRect() 获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置。

4.插入节点 insertNode,创建节点 createElement,移除子节点 removeChild  了解一下JS在页面光标位置插入新内容 - 精神领袖 - 博客园

总体思路:

            首先获取输入框中输入#号时光标的位置(只能获取到文本中第几位,非可视区域的位置),并保存其位置。然后在当前位置插入一个创建的节点,并获取它的可视区域位置(left,top值),保存后删除该节点。然后通过简单运算,获取到下拉框的绝对定位的left,top值,赋值给下拉框并让其显示。点击下拉框中的任意一项,根据输入#号时的光标位置进行字符串的截取并添加。这样就会插入到输入框中。

效果如图



效果如图


插入后效果

code-img


keyup事件


选中下拉框的操作

注意项


1.Chrome 浏览器,input标签oninput事件中,有 event.data 属性,即为输入的值,刚开始就是使用的 这个属性,在chrome完美运行,退格键,左右键完美运行,无bug。但是忽略了一点,这个属性在 firefox,ie不存在。故在这里,不能够实现。

2.onblur 事件触发 比 onclick 事件快。在弹出下拉框时,我们需要去点击下拉框的内容,就内容插入到我们input输入框内,并将下拉框隐藏。自然而然的会写一个 onblur事件来 是 show 为false,在下拉框的ul中执行点击操作。在实际中 blur 事件先触发,下拉框就会消失掉,这个时候可点击的dom结构已不存在,也就不会触发该事件。解决方法是在 blur事件中,增加一个延时器,延时 将 show 置为 false;

3.可输入的div,测试中不支持input事件。如有错误,还望提出。

你可能感兴趣的:(模仿微信@效果)