欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

如何实现textarea中输入@在右下方出现一个提示框?

程序员文章站 2022-08-04 12:03:17
最近在csdn问答板块看到了一个问题: 如何实现textarea中输入@在右下方出现一个提示框? 主要难点是光标所在的位置,网上找了下,大多是获取光标所在的字符位数,而不是...

最近在csdn问答板块看到了一个问题:

如何实现textarea中输入@在右下方出现一个提示框?

如何实现textarea中输入@在右下方出现一个提示框?

主要难点是光标所在的位置,网上找了下,大多是获取光标所在的字符位数,而不是距离开头的宽高,所以舍弃。

但是本文还是需要这个技术,来判断光标是不是在文本最后。

//输入框获取光标
function getPosition(element) {
    var cursorPos = 0;
    if (document.selection) {//IE
        var selectRange = document.selection.createRange();
        selectRange.moveStart('character', -element.value.length);
        cursorPos = selectRange.text.length;
    } else if (element.selectionStart || element.selectionStart == '0') {
        cursorPos = element.selectionStart;
    }
    return cursorPos;
}

新思路:计算文本中有多少和字节,2个字节为一个字,根据文本的字体大小和字数获取到文本的长度,由这个长度再根据所处环境计算提示框的位置。

所处环境指的是该元素所在位置,光标相对于文本域所在位置(根据总长度和文本域宽度判断在光标第几行的哪个位置))。

下面是一个简单的demo,没有计算光标所在文本域的位置及该元素所在位置,有需要的可以自行计算。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        *{padding:0;margin:0;}
        .box{position:relatuve;}
        #ipt{
            font-size:16px;
            padding-left:5px;
            height:30px;
            line-height:30px;
        }
        #list{
            position:absolute;
            list-style:none;
            width:150px;
            display:none;
        }
        #list li{height:25px;line-height:25px;}
        #list li:hover{background:#efefef;cursor:pointer;}
    </style>
</head>
<body>
    <p class='box'>
        <input type="text" id='ipt'>
        <ul id='list'>
            <li>qq.com</li><li>sina.com</li><li>163.com</li>
        </ul>
    </p>

    <script>
        var ipt = document.getElementById('ipt');   
        var list = document.getElementById('list');

        ipt.oninput = function(e){
            //console.log(e)
            //获取光标位置
            var position = getPosition(ipt);
            console.log(position,(ipt.value+'').length)
            //如果光标在文本最后面,且最后一个是@
            if((position == (ipt.value+'').length) && /@$/.test(ipt.value)){
                //把双字节的替换成两个单字节的然后再获得长度 
                var len = (ipt.value || '').replace(/[^\x00-\xff]/g,"01").length/2;
                var fz = parseFloat(window.getComputedStyle(ipt).fontSize);
                var wd = parseFloat(window.getComputedStyle(ipt).width);
                list.style.left = fz*len>wd?wd:fz*len + "px";
                list.style.display = "block";
            }else{
                list.style.display = "none";
            }
        }
        for(var i=0;i<list.children.length;i++){
            list.children[i].onclick = function(e){
                ipt.value += e.target.innerHTML;
                list.style.display = "none";
            }
        }
        //输入框获取光标
        function getPosition(element) {
            var cursorPos = 0;
            if (document.selection) {//IE
                var selectRange = document.selection.createRange();
                selectRange.moveStart('character', -element.value.length);
                cursorPos = selectRange.text.length;
            } else if (element.selectionStart || element.selectionStart == '0') {
                cursorPos = element.selectionStart;
            }
            return cursorPos;
        }
    </script>
</body>
</html>