亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

js完美實現@提到好友特效(兼容各大瀏覽器)

2019-11-20 12:55:26
字體:
來源:轉載
供稿:網友

要求

1.輸入@時,彈出匹配的好友菜單

2.光標進入包含有"@好友"的標簽時,彈出菜單

3.按backspace刪除時,如果光標前面是包含有"@好友"的標簽,彈出菜單

4.兼容ie,firefox.

具體做法

針對要求一,很自然的會想到對輸入框綁定事件。這里要綁定mousedown,而不是mouseup.因為如果是mouseup的話,用event.preventDefault()是無法阻止鍵盤輸入@的。另外,這里在事件回調中用return false也是起不了作用的。

綁定mousedown事件后,就要插入自定義的包含有"@好友"的標簽了。新浪微博的輸入框是用textarea做的,無法知道其內部是怎樣處理的,只好看百度貼吧了。

可以看到,貼吧是插入了<span class='at'></span>標簽。這應該是方便后臺用正則表達式匹配。

具體的

復制代碼 代碼如下:

        vm.check_key=function(e){
            var editor=$('editor'),range;
            if(e.shiftKey&&e.keyCode==50){
                if (document.selection && document.selection.createRange) {
                    range = document.selection.createRange();
                    range.pasteHTML(" <span id='at"+at_index+"' class='at_span'>@</span> ");
                }else{
                    document.execCommand("insertHtml", false," <span id='at"+at_index+"' class='at_span'>@</span> ");
                }
                e.preventDefault();
            }
        };

這里需要在光標處插入,所以用到了range.

然后就是菜單顯示了,關鍵在于怎么定位。我的做法很垃圾,就是為插入的span添加id,然后根據span id的位置為菜單定位。如果有更好的做法,請告訴我一聲。

具體的

復制代碼 代碼如下:

    function at_box_show(at){
        var at_pos=avalon($(at)).position();
        $('at_box').style.left=at_pos.left+'px';
        $('at_box').style.top=at_pos.top+16+'px';
        $('at_box').style.display='block';
    }
    var at_index=0,cur_index=0;
    avalon.define('editor', function(vm) {
        vm.item_click=function(){
            $('at'+cur_index).innerHTML="@"+this.innerHTML;
            $('at_box').style.display='none';
            at_index++;
        };
        vm.check_key=function(e){
            var editor=$('editor'),a=getCharacterPrecedingCaret(editor),range;
            if(e.shiftKey&&e.keyCode==50){
                if (document.selection && document.selection.createRange) {
                    range = document.selection.createRange();
                    range.pasteHTML(" <span id='at"+at_index+"' class='at_span'>@</span> ");
                }else{
                    document.execCommand("insertHtml", false," <span id='at"+at_index+"' class='at_span'>@</span> ");
                }
                at_box_show('at'+at_index);
                cur_index=at_index;
                e.preventDefault();
            }
        };
    });

at_show_box根據新插入的span id,為at_box定位,然后顯示菜單。cur_index表示光標當前所在的span id.設置這個變量因為用戶可能倒回去改已經插入的span,而at_index是一直遞增的,所以這里就還需要一個變量。

用戶點擊菜單中好友項,觸發item_click回調?;卣{里就是將好友名字用innserHTML添加到當前span里面.然后隱藏菜單,at_index++。

上面是監聽shift+@,接著是監聽backspace刪除。

復制代碼 代碼如下:

    function getTextBeforeCursor(containerEl) {
        var precedingChar = "", sel, range, precedingRange;
        if (window.getSelection) {
            sel = window.getSelection();
            if (sel.rangeCount > 0) {
                range = sel.getRangeAt(0).cloneRange();
                range.collapse(true);
                range.setStart(containerEl, 0);
                precedingChar = range.cloneContents();
            }
        } else if ( (sel = document.selection)) {
            range = sel.createRange();
            precedingRange = range.duplicate();
            precedingRange.moveToElementText(containerEl);
            precedingRange.setEndPoint("EndToStart", range);
            precedingChar = precedingRange.htmlText;
        }
        return precedingChar;
    }

getTextBeforeCursor的作用是獲取光標前的內容.由于兼容性,這個函數在標準瀏覽器中可以得到是光標前所有內容的DocumentFragment,而在ie中就只能得到文本(不是node)了,不過這個html字符串可以轉換成DocumentFragment.在avalon中用parseHTML就可以將html字符串變成node了。jquery中用$(html)[0]也能得到node.

有了這個函數,再用lastChild就可以判斷光標是不是在光標前html的lastChild里,并且這個lastChild是span。

具體的

復制代碼 代碼如下:

               var a=getTextBeforeCursor($('editor'));
                       if(e.keyCode==8){
                if(!-[1,]){
                    var b=avalon.parseHTML(a).lastChild;
                }else{
                    var b=a.lastChild;
                }
                if(b.nodeType==1&&b.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=getTextBeforeCursor(editor);
            if(!-[1,]){
                var b=avalon.parseHTML(getTextBeforeCursor(editor)).lastChild;
            }else{
                var b=a.lastChild;
            }
            if(b!=null&&b.nodeType==1&&b.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更新菜單,字符匹配我就不做了

效果

firefox

ie8

ie7

ie6

下載

以上就是本文所述的全部內容了,希望對大家了解javascript能夠有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久精品久久久久久| 中文字幕亚洲综合久久| 亚洲欧美中文字幕在线一区| 亚洲国产精品va在线| 亚洲精品欧美一区二区三区| 欧美专区福利在线| 亚洲人高潮女人毛茸茸| 国产成人精品在线观看| 欧美丰满少妇xxxxx做受| 欧美孕妇孕交黑巨大网站| 国产欧美一区二区三区久久人妖| 欧美日韩国产123| 中文字幕一区日韩电影| 一区二区欧美日韩视频| 欧洲日本亚洲国产区| 欧美性猛交xxxx富婆弯腰| 91国内揄拍国内精品对白| 日本国产一区二区三区| 欧美电影在线观看网站| 日韩av手机在线| 精品欧美一区二区三区| 精品视频久久久| 欧美丝袜一区二区| 欧美日韩国产一区中文午夜| 欧美成人在线免费视频| 国产91在线高潮白浆在线观看| 欧亚精品在线观看| 久久久久久久国产精品| 色噜噜狠狠狠综合曰曰曰88av| 亚洲精品福利资源站| 久久人人爽国产| 日韩成人在线免费观看| 亚洲国产小视频在线观看| 精品电影在线观看| 久久久av电影| 亚洲xxxxx| 国产一区二区三区直播精品电影| 欧美日韩中文字幕综合视频| 欧美国产高跟鞋裸体秀xxxhd| 亚洲精品自拍偷拍| 国产福利视频一区二区| 51精品国产黑色丝袜高跟鞋| 亚洲视频日韩精品| 国产精品中文久久久久久久| 色爱av美腿丝袜综合粉嫩av| 欧美日本啪啪无遮挡网站| 久久久www成人免费精品| 韩国精品美女www爽爽爽视频| 久久婷婷国产麻豆91天堂| 欧美激情视频在线免费观看 欧美视频免费一| 欧美高清videos高潮hd| 国产日韩精品入口| 夜夜嗨av色一区二区不卡| 69影院欧美专区视频| 国产成人自拍视频在线观看| 久久国产精品久久久久久| 成人黄色免费在线观看| 91夜夜未满十八勿入爽爽影院| 日韩av电影免费观看高清| 国产成人在线亚洲欧美| 中文字幕久久久av一区| 亚洲欧美日本另类| 日韩成人av在线播放| 国产精品视频26uuu| 久久精品成人欧美大片| 日本在线精品视频| 黑人极品videos精品欧美裸| 一级做a爰片久久毛片美女图片| 国产午夜精品一区二区三区| 亚洲欧美激情四射在线日| 一本一道久久a久久精品逆3p| 欧美综合第一页| 欧美性猛交xxxx| 日韩毛片在线看| 日韩av在线网页| 亚洲a∨日韩av高清在线观看| 欧美性猛交xxx| 日韩国产中文字幕| 秋霞av国产精品一区| 国产美女精品视频| 91在线中文字幕| 俺也去精品视频在线观看| 69精品小视频| 精品国产美女在线| 久久久久久国产精品三级玉女聊斋| 亚洲激情久久久| 中文字幕欧美亚洲| 亚洲精品小视频在线观看| 国产视频久久久| 中文字幕亚洲专区| 欧美视频不卡中文| 欧美性69xxxx肥| 国产男女猛烈无遮挡91| 欧美国产亚洲精品久久久8v| 91精品久久久久久久久久| 国产欧美日韩免费看aⅴ视频| 亚洲性xxxx| 国产日韩欧美黄色| 亚洲天堂视频在线观看| 日韩精品一区二区视频| 国产精品久久久久久久久借妻| 亚洲欧美国产精品久久久久久久| 色播久久人人爽人人爽人人片视av| 高清一区二区三区四区五区| 国产一区二区免费| 欧美做受高潮电影o| 亚洲精品午夜精品| 久久午夜a级毛片| 日韩精品在线视频观看| 亚洲国产高清高潮精品美女| 日韩中文字幕视频在线观看| 亚洲精品99久久久久中文字幕| 国产精品一区久久久| 91产国在线观看动作片喷水| 久久久久久综合网天天| 国产精品麻豆va在线播放| 亚洲免费视频一区二区| 日韩成人中文电影| 国内精品久久久久久| 亚洲色图偷窥自拍| 国产午夜精品麻豆| 成人在线国产精品| 国产91久久婷婷一区二区| 欧美日韩午夜视频在线观看| 精品视频久久久久久| 欧美电影在线播放| 国产免费一区视频观看免费| 亚洲va久久久噜噜噜| 国产精品视频yy9099| 国产成人aa精品一区在线播放| 精品国产精品三级精品av网址| 国产精品视频久久| 一区二区三区回区在观看免费视频| 一区二区三区国产视频| 国产精品福利无圣光在线一区| 在线亚洲欧美视频| 欧美日韩性视频在线| 欧美一区二区影院| 97视频免费在线观看| 久久久免费观看| 国产一区二区三区在线播放免费观看| 亚洲精品v天堂中文字幕| 亚洲成色777777女色窝| 26uuu国产精品视频| 97在线视频免费| 亚洲另类欧美自拍| 亚洲欧美国产一区二区三区| 国产精品极品在线| 久久久久久国产精品| 另类专区欧美制服同性| 亚洲视频一区二区三区| 欧美精品video| 国产精品久久99久久| 欧美成aaa人片免费看| 在线观看久久久久久| 亚洲情综合五月天| 日韩网站免费观看高清| 91精品国产91久久久| 在线观看亚洲区| 日韩av一区二区在线观看| 91sa在线看| 久久影院免费观看| 国产精品极品美女在线观看免费| 久久亚洲国产精品成人av秋霞|