成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

業(yè)務(wù)開發(fā)情境之:實現(xiàn)一個@功能

BetaRabbit / 603人閱讀

摘要:我們算出這個相對于頁面左上角的和,就是等下選框相對于文本框的和的距離,因為我們選框是絕對定位相對于,所以在加上文本框相對于的和就是我們選框所要定位的和了。

最近接到了一個業(yè)務(wù)需求,讓用戶能夠通過網(wǎng)頁聊天框的方式在線完成交易,一個用戶可能有多個業(yè)務(wù)群,其中一個功能就是要@人,@這個功能在現(xiàn)實的應(yīng)用中經(jīng)常可以遇到,比如微博、QQ都有@功能,今天我們就以前端的方式談?wù)勗趺匆徊讲綄崿F(xiàn)一個@功能。

@功能涉及到的原生API

obj.selectionStart獲取光標(biāo)位置

obj.setSelectionRange(n, n)設(shè)置光標(biāo)位置

keyup事件和keydown事件

1.搭建我們的html文件

幾個地方特別說明下:實際操作中,我們出現(xiàn)了@選框要實時更新列表數(shù)據(jù),在這個dome中我們先用靜態(tài)列表代替,效果是一樣的。然后這個pre是用來定位@選框用的,注意pre大小,字體要和輸入框一樣,并將pre絕對定位到頁面的左上角,并設(shè)置不可見。








2、實現(xiàn)@選框出現(xiàn),并將@選框定位到當(dāng)前光標(biāo)右下角

具體實現(xiàn)思路:檢測鍵盤的左邊是否是@字符,如果有的話,將輸入框光標(biāo)前面的內(nèi)容復(fù)制一份到pre,并在pre后面增加一個span,這個sapn用來協(xié)助定位@選框的。我們算出這個span相對于頁面左上角的left和top,就是等下@選框相對于文本框的left和top的距離,因為我們@選框是絕對定位相對于body,所以在加上文本框相對于body的offsetLeft和offsetTop就是我們@選框所要定位的left和top了。

//全局定義一個變量為光標(biāo)位置
var cursor;
//文本框綁定keyup事件,檢測輸入
textapp.addEventListener("keyup", function(e){
    //獲取光標(biāo)
    cursor = textapp.selectionStart;
    // 當(dāng)前光標(biāo)所在位置的前一位為@字符,出現(xiàn)@選框
    if(textapp.value.substring(0,cursor).charAt(cursor-1) === "@"){
        // 判斷最后一個字符是否為@
        pre_text.innerHTML = textapp.value.substring(0,cursor);
        pre_text.innerHTML += "";
        var span = document.getElementById("proxy");
        var conX = textapp.offsetLeft;
        var conY = textapp.offsetTop;
        var spanX = span.offsetLeft + conX;
        var spanY = span.offsetTop + conY;
        selectuser.style.left = spanX + "px";
        selectuser.style.top = spanY + "px";
        selectuser.style.display = "block";
        //設(shè)置@選框的默認(rèn)樣式
        listSet();
    }else{
        selectuser.style.display = "none";
    }    
})
// @框默認(rèn)設(shè)置
function listSet() {
    var list = $("#selectlist");
    list.focus();
    $("#selectlist").find("li").eq(0).addClass("hover").siblings("li").removeClass("hover");
    $("#selectuser").scrollTop(0);
}
3.鍵盤直接操作@選框

當(dāng)我們的@選框出現(xiàn)了,并且定位好了,出現(xiàn)在我們想要的位置了,我們直接用鍵盤上下去選擇所要@的人了(鼠標(biāo)點擊選中情況等下介紹)。這里我們要考慮的點有兩個:1.當(dāng)我們光標(biāo)在輸入框最后,我們按上下左右光標(biāo)就會變化位置。2.選擇之后光標(biāo)位置的變化。

1的解決辦法是:我們光標(biāo)位置的變化是在keydown的時候執(zhí)行的,keydown是先于我們的keyup之前執(zhí)行的,所以我們就要在keydown的時候就阻止默認(rèn),防止光標(biāo)移動

textapp.addEventListener("keydown", function(e){
    //建立在@選框出現(xiàn)的情況下
    if(selectuser.style.display == "block"){
        var code = e.keyCode;
        //左右回車時阻止默認(rèn),防止光標(biāo)移動
        if(code == 38 || code == 40 || code == 13){
            e.preventDefault();
        }
    }
})

2.選中@人后,我們用setSelectionRange來設(shè)置光標(biāo)的位置,將下面這段代碼輸入框keyup綁定事件里面,放在最前面

    // 當(dāng)@選框存在時,判斷鍵盤上移,下移,以及回車選中事件
    if(selectuser.style.display == "block"){
        var code = e.keyCode;
        if(code == 38){
            // 上移
            preCode();
            return;
        }else if (code == 40){
            // 下移
            nextCode();
            return;
        }else if(code == 13){
            //回車選中@人
            var textname = "";
            $("#selectlist").find("li").each(function(){
                if($(this).hasClass("hover")){
                    textname = $(this).html();
                }
            });
            //@完后文本框顯示內(nèi)容
            $("#app").val(getText($("#app").val(), cursor, textname));
            //添加后光標(biāo)的位置
            var n = textname.length + 1 + cursor;
            //設(shè)置光標(biāo)的位置
            textapp.setSelectionRange(n, n);
            //選中后隱藏@選框
            $("#selectuser").hide();
            return;
        }
    }

上面這段代碼我們用到了三個函數(shù)

    // 鍵盤上移
    function preCode() {
        var index = $("#selectlist").find(".hover").index();
        if(index == 0){
            return;
        }else{
            index--;
            $("#selectuser").scrollTop(index * 26);
            $("#selectlist").find("li").eq(index).addClass("hover").siblings("li").removeClass("hover");
        }
    }
    // 鍵盤下移
    function nextCode() {
        var len = $("#selectlist").find("li").length;
        var index = $("#selectlist").find(".hover").index();
        if(index == len-1){
            return;
        }else{
            index++;
            $("#selectuser").scrollTop(index * 26);
            $("#selectlist").find("li").eq(index).addClass("hover").siblings("li").removeClass("hover");
        }
    }
    //@人的文本格式,為后面加一個空格,后面用到 
    function getText(app, cursor, textname) {
        var text1 = app.substring(0, cursor);
        var text2 = app.substring(cursor);
        return text1 + textname + " " + text2;
    }
4.提交操作時,取出有效的@人

當(dāng)我們消息輸入完成后,點擊發(fā)送(我們這里用個提交按鈕)。我們要檢測這個消息中是否有@人,并把當(dāng)前這條消息有效的@人取出來,這里注意并不是說我們之前選中了@某個人后就有效了,可能在這個人的名字中我又輸入了其他的字符。所以我們要在發(fā)送消息的時候做一次檢查,把有效的@人提取出來,并且以后臺規(guī)定的數(shù)據(jù)格式。(我們暫且規(guī)定為數(shù)組吧)。

    // 提交
    $("#submit").on("click", function() {
        var msg = $("#app").val();
        //檢測輸入框是否為空
        if(msg === ""){
            alert("內(nèi)容不能為空!");
            return;
        }
        //返回有效@人列表
        var arr = handleMsg(msg);
    });
    //操作信息提取有效@人
    function handleMsg(msg) {
        //存放有效@人id的數(shù)組
        var At = [];
        //正則驗證吧以@開頭空格結(jié)束的選出來已數(shù)組的形式
        var arrAt = msg.match(/@{1}([u4e00-u9fa5]|w)+s{1}/g);
        //說明沒有@人,直接韓慧
        if(arrAt === null){
            console.log("沒有選中@的人!");
            return At;
        }
        // 對arrAt數(shù)組即當(dāng)前信息@人的列表進(jìn)行遍歷
        for (var i = 0; i < arrAt.length; i++) {
            var username = arrAt[i].replace("@", "").trim();
            // 對比當(dāng)前群組人選
            var grounpuser = $("#selectlist").find("li");
            for (var j = 0; j < grounpuser.length; j++) {
                //如果名字相同,則把id放進(jìn)數(shù)組內(nèi)容
                if(username == grounpuser.eq(j).html()){
                    var uid = grounpuser.eq(j).attr("uid");
                    At.push(uid);
                    break;
                }
            };
        };
        return At;
    }
完結(jié)

好了,一個@的功能已經(jīng)基本實現(xiàn)了,剩下的就是通過ajax與后臺的交互了。如果你覺得本篇文章對你有收獲請贊下,也可以關(guān)注下我,分享工作,學(xué)習(xí)的前端個人感悟分享。github

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/79783.html

相關(guān)文章

  • 業(yè)務(wù)開發(fā)情境:文本框的base64編碼圖片粘貼直接上傳七牛

    摘要:我們的功能需要用到的接口事件讀取完成,無論成功與否,還有方法將文件讀取為。檢測是否為圖片類型圖片的編碼這里設(shè)置獲取的數(shù)據(jù)獲取后臺的給的將文件讀取為上傳事件當(dāng)?shù)臅r候說明我們成功的把圖片傳上七牛了,并且七牛給我們返回了一個字符串。 最近在做的一個聊天消息的功能。有個圖片上傳的功能,可以通過按鈕上傳也可以通過Ctrl+V上傳。按鈕上傳的我們可以通過七牛的API就可以做了,我們現(xiàn)在來說說Ctr...

    xiao7cn 評論0 收藏0
  • 業(yè)務(wù)開發(fā)情境實現(xiàn)一個@功能

    摘要:我們算出這個相對于頁面左上角的和,就是等下選框相對于文本框的和的距離,因為我們選框是絕對定位相對于,所以在加上文本框相對于的和就是我們選框所要定位的和了。 最近接到了一個業(yè)務(wù)需求,讓用戶能夠通過網(wǎng)頁聊天框的方式在線完成交易,一個用戶可能有多個業(yè)務(wù)群,其中一個功能就是要@人,@這個功能在現(xiàn)實的應(yīng)用中經(jīng)??梢杂龅剑热缥⒉?、QQ都有@功能,今天我們就以前端的方式談?wù)勗趺匆徊讲綄崿F(xiàn)一個@功能...

    xuexiangjys 評論0 收藏0
  • 函數(shù)式編程與面向?qū)ο缶幊蘙5]:編程的本質(zhì)

    摘要:函數(shù)式編程與面向?qū)ο缶幊叹幊痰谋举|(zhì)之劍目錄編程的本質(zhì)讀到兩篇文章寫的不錯綜合摘錄一下復(fù)合是編程的本質(zhì)函數(shù)式程序員在洞察問題方面會遵循一個奇特的路線。在面向?qū)ο缶幊讨?,類或接口的聲明就是表面? 函數(shù)式編程與面向?qū)ο缶幊蘙5]:編程的本質(zhì) 之劍 2016.5.6 01:26:31 編程的本質(zhì) 讀到兩篇文章,寫的不錯, 綜合摘錄一下 復(fù)合是編程的本質(zhì) 函數(shù)式程序員在洞察問題方面會遵循...

    miracledan 評論0 收藏0
  • 漫談 | 區(qū)塊鏈會是哈貝馬斯所說的“理想話語情境”嗎?

    摘要:區(qū)塊鏈科技原罪還是交往理性迄今為止,我們尚未見到從中本聰開始的任何一位區(qū)塊鏈開發(fā)者提及哈貝馬斯,但區(qū)塊鏈卻奇妙契合了哈貝馬斯對理想話語情境的描述。 生活在我們這個時代的人,不可避免的活在消費控制之下。著名的哲學(xué)家馬爾庫塞說,人們似乎是為商品而生活。小轎車、高清晰度的傳真裝置、錯層式家庭住宅以及廚房設(shè)備成了人們生活的靈魂。人們被被消費欲望所控制,自主性喪失,個性泯滅,成為單向度的人。 s...

    andong777 評論0 收藏0
  • JAVA 序列化

    摘要:靜態(tài)變量序列化情境查看清單的代碼。之所以打印的原因在于序列化時,并不保存靜態(tài)變量,這其實比較容易理解,序列化保存的是對象的狀態(tài),靜態(tài)變量屬于類的狀態(tài),因此序列化并不保存靜態(tài)變量。解決要想將父類對象也序列化,就需要讓父類也實現(xiàn)接口。 原文 https://www.ibm.com/developer...  引言 將 Java 對象序列化為二進(jìn)制文件的 Java 序列化技術(shù)是 Java 系...

    GeekQiaQia 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<