手机版

js完美实现@提到好友特效(兼容各大浏览器)

时间:2021-10-12 来源:互联网 编辑:宝哥软件园 浏览:

要求

1.输入@时,弹出匹配的好友菜单

2.光标进入包含有@好友'的标签时,弹出菜单

3.按退格键删除时,如果光标前面是包含有@好友'的标签,弹出菜单

4.兼容比如火狐。

具体做法

针对要求一,很自然的会想到对输入框绑定事件。这里要绑定放下鼠标,而不是鼠标向上。因为如果是鼠标向上的话,用event.preventDefault()是无法阻止键盘输入@的。另外,这里在事件回调中用返回错误的也是起不了作用的。

绑定鼠标放下事件后,就要插入自定义的包含有@好友'的标签了。新浪微博的输入框是用文本区域做的,无法知道其内部是怎样处理的,只好看百度贴吧了。

可以看到,贴吧是插入了span class='at'/span标签。这应该是方便后台用正则表达式匹配。

具体的

复制代码代码如下:虚拟机。check _ key=function(e){ var editor=$(' editor ')、rangeif(e . shift keye。键码==50){ if(文档。选择文档。选择。创建范围){ range=document。选择。创建范围();范围。PasteHTML(' span id=' at ' at _ index ' ' class=' at _ span ' @/span ');} else { document。exec命令(' insert HTMl ',false,' span id=' at ' at _ index ' ' class=' at _ span ' @/span ');} e . PreventDefault();} };

这里需要在光标处插入,所以用到了范围。

然后就是菜单显示了,关键在于怎么定位。我的做法很垃圾,就是为插入的跨度添加id,然后根据跨度编号的位置为菜单定位。如果有更好的做法,请告诉我一声。

具体的

复制代码代码如下:函数at _ box _ show(at){ var at _ pos=Avalon($(at)).position();$(“at _ box”)。风格。left=at _ pos。左“px”;$(“at _ box”)。风格。top=at _ pos。前16 ' px$(“at _ box”)。风格。display=" block} var at_index=0,cur _ index=0;avalon.define('编辑器',函数(VM){ VM。item _ click=function(){ $(' cur _ index处的').innerHTMl="@ "这。innerHTMl$(“at _ box”)。风格。display=" noneat _ index };虚拟机。check _ key=function(e){ var editor=$(' editor '),a=GetCharacterProcendingCaret(editor),rangeif(e . shift keye。键码==50){ if(文档。选择文档。选择。创建范围){ range=document。选择。创建范围();范围。PasteHTML(' span id=' at ' at _ index ' ' class=' at _ span ' @/span ');} else { document。exec命令(' insert HTMl ',false,' span id=' at ' at _ index ' ' class=' at _ span ' @/span ');} at _ box _ show(' at ' at _ index);cur _ index=at _ indexe。PreventDefault();} };});

at_show_box根据新插入的跨度id,为at_box定位,然后显示菜单当前索引表示光标当前所在的跨度身份证.设置这个变量因为用户可能倒回去改已经插入的跨度,而at_index是一直递增的,所以这里就还需要一个变量。

用户点击菜单中好友项,触发项目点击回调。回调里就是将好友名字用innserHTML添加到当前跨度里面。然后隐藏菜单,位于_索引。

上面是监听[emailprotected],接着是监听退格键删除。

复制代码代码如下:函数GetTextBeforeCursor(容器rel){ var precing char=' ',sel,range,precedingRangeif(窗口。getselection){ sel=window。getselection();if(sel。范围计数0){范围=sel。getrange位于(0).cloneRange();范围。崩溃(真);范围。setstart(容器rel,0);精确字符=范围。clone contents();} } else if((sel=document。selection)){ range=sel。创建范围();预测范围=范围。重复();预测范围。movetoelementtext(容器rel);正在缩小范围。setendpoint(' endto start ',range);沉淀字符=沉淀范围。html文本;}返回precedingChar }

getTextBeforeCursor的作用是获取光标前的内容。由于兼容性,这个函数在标准浏览器中可以得到是光标前所有内容的文档片段,而在工程师协会中就只能得到文本(不是节点)了,不过这个超文本标记语言字符串可以转换成文档片段.在阿瓦隆中用parseHTML就可以将超文本标记语言字符串变成结节了jquery。中用$(html)[0]也能得到节点。

有了这个函数,就可以用lastChild来判断光标是否在html的lastChild中,在光标之前,这个lastChild是span。

特殊的

复制代码如下: VARA=gettextbeforecorsor($(' editor '));if(e.keyCode==8){ if(!-[1,]){ var b=avalon.parseHTML(a)。lastChild} else { var b=a.lastChild} if(b . nodetype==1b . nodename==' SPAN '){ var id=b . id;cur _ index=b . id . substring(2);at _ box _ show(b . id);} else $(“at _ box”). style . display=“none”;}

最后,光标进入span选项卡并显示菜单。这显然需要绑定鼠标事件。这里绑定mouseup,因为如果绑定mousedown,需要再次单击span选项卡上的鼠标来显示菜单。至于原理,跟上面差不多。

复制代码如下:VM。check _ mouse=function(e){ var editor=$(' editor '),a=gettextbeforecorsor(editor);if(!--[1,]){ var b=Avalon . parsehtml(gettextbeforecourus(编辑器))。lastChild} else { var b=a.lastChild} if(b!=nullb . nodetype==1b . nodename==' SPAN '){ var id=b . id;cur _ index=b . id . substring(2);at _ box _ show(b . id);} else $(“at _ box”). style . display=“none”;};

注意:如果光标在span中,需要取出它的id,at _ box根据这个id定位。此外,有必要重置cur_index。

至于ajax更新菜单,我就不做字符匹配了。

影响

火狐浏览器

ie8

ie7

ie6

下载

以上就是本文的全部内容。希望对大家理解javascript有帮助。

版权声明:js完美实现@提到好友特效(兼容各大浏览器)是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。