首頁  >  文章  >  web前端  >  js完美實現@提到好友特效(相容各大瀏覽器)_javascript技巧

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

WBOY
WBOY原創
2016-05-16 16:09:231435瀏覽

要求

1.輸入@時,彈出符合的好友選單

2.遊標進入包含有"@好友"的標籤時,彈出選單

3.按backspace刪除時,若遊標前方是包含有"@好友"的標籤,彈出式選單

4.相容ie,firefox.

具體做法

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

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

可以看到,貼吧是插入了標籤。這應該是方便後台用正規表示式匹配。

具體的

複製程式碼 程式碼如下:

        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();
                                    }else{
                                document.execCommand("insertHtml", false,"                  e.preventDefault();
            }
        };


這裡要在遊標處插入,所以用到了range.

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

具體的

複製程式碼 程式碼如下:

    函數 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('編輯器', function(vm) {
        vm.item_click=function(){
            $('at' cur_index).innerHTML="@" this.innerHTML;
            $('at_box').style.display='none';
            at_index ;
        };
        vm.check_key=函數(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(" @ ");
                }其他{
                    document.execCommand("insertHtml", false," @ ");
                }
                at_box_show('at' at_index);
                cur_index=at_index;
                e.preventDefault();
            }
        };
    });

at_show_box根據新插入的span id,為at_box定位,然後顯示選單。 ,所以這裡還需要一個變數。

使用者點選選單中好友項,觸發item_click回呼隱藏。

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

複製程式碼程式碼如下:

    函數 getTextBeforeCursor(containerEl) {
        var previousChar = "", sel, range, previousRange;
        if (window.getSelection) {
            sel = window.getSelection();
            if (sel.rangeCount > 0) {
                range = sel.getRangeAt(0).cloneRange();
                range.collapse(true);
                range.setStart(containerEl, 0);
                previousChar = range.cloneContents();
            }
        } else if ( (sel = document.selection)) {
            range = sel.createRange();
            previousRange = range.duplicate();
            previousRange.moveToElementText(containerEl);
            previousRange.setEndPoint("EndToStart", range);
            previousChar = previousRange.htmlText;
        }
        傳回前一個字元;
    }

getTextBeforeCursor的作用只能是獲取對話框前面的內容。這個html字串可以轉換成DocumentFragment。

有了這個函數,再用lastChild就可以判斷標題是不是在前頭html的lastChild裡,而這個lastChild是span。

具體的

               var a=getTextBeforeCursor($('editor'));
                       if(e.keyCode==8){
                if(!-[1,]){
                    var b=avalon.parseHTML(a).lastChild;
                }其他{
                    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);
                }其他
                    $('at_box').style.display='none';
            }


最後是滑鼠進入span標籤,顯示選單。上面差不多。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn