jquery实现input智能提示信息以及光标定位处选中特定的文字

在本文中,我们将会达到一下目的

  1. 将 input 文本输入框的内容格式化处理,即用户输入的内容我们会自动处理成规则的格式,以便后续的处理

  2. 当光标定位到 input 输入框中的某个元素时,js会将这个有效的部分文本选中,而不是选中全部的文本

  3. 当用户在输入框中输入信息时,系统给出输入提示信息

注意,本例需要jquery.js文件,读者请先自行下载jquery.js文件,然后把文件引入下面的网页中。

代码实现如下:

test.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <meta charset="utf-8"/>
    <style type="text/css">
        .search {
            left: 0;
            position: relative;
        }

        #auto_div {
            display: none;
            /*width: 100px;*/
            border: 1px #74c0f9 solid;
            background: #FFF;
            position: absolute;
            /*top: 24px;*/
            /*left: 0;*/
            color: #323232;
        }
    </style>
    <script src="jquery.js" type="text/javascript"></script>
    <script type="text/javascript" src="textarea-editor.js?ver=1"></script>
    <script type="text/javascript">

        var old_value = "";
        var highlightindex = -1;   //高亮
        var tx;
        var te;
        /**
         * 获取光标在input中的位置
         * @param auto 提示信息显示的地方
         * @param data DOM对象
         * @param mylist json对象,要提示的信息
         */
        function AutoComplete(auto, data, mylist) {
            if (data.value != old_value || old_value == "") {
                var autoNode =auto;   //缓存对象(弹出框)

                var framePos = getLablePosition(data);
                auto[0].style.top = framePos.h + framePos.y + "px";
                auto[0].style.left = framePos.x+"px";

                var carlist = new Array();
                var n = 0;
                var temp = data.value, tempid = 0;
                var po = getPosition(data);
                for (var j = po; j >= 0; j--) {
                    if (j - 1 == 0 || temp.charAt(j - 1) === ' ') {
                        old_value = temp.substring(j - 1, po).replace(/(^\s*)|(\s*$)/g, "");
                        tempid = j;
                        break;
                    }
                }
                for (i in mylist) {
                    if (mylist[i].indexOf(old_value) >= 0) {
                        carlist[n++] = mylist[i];
                    }
                }
                if (carlist.length == 0) {
                    auto.hide();
                    return;
                }
                auto.empty();  //清空上次的记录
                for (i in carlist) {
                    var wordNode = carlist[i];   //弹出框里的每一条内容 
                    var newDivNode = $("<div>").attr("id", i);    //设置每个节点的id值
                    newDivNode.attr("style", "font:14px/25px arial;height:25px;width:" + (framePos.w - 17) + "px" + ";padding:0 8px;cursor: pointer;");
                    newDivNode.html(wordNode).appendTo(auto);  //追加到弹出框
                    //鼠标移入高亮,移开不高亮
                    newDivNode.mouseover(function () {
                        if (highlightindex != -1) {        //原来高亮的节点要取消高亮(是-1就不需要了)
                            auto.children("div").eq(highlightindex).css("background-color", "white");
                        }
                        //记录新的高亮节点索引
                        highlightindex = $(this).attr("id");
                        $(this).css("background-color", "#ebebeb");
                    });
                    newDivNode.mouseout(function () {
                        $(this).css("background-color", "white");
                    });
                    //鼠标点击文字上屏
                    newDivNode.click(function () {
                        //取出高亮节点的文本内容
                        var comText = auto.hide().children("div").eq(highlightindex).text();
                        highlightindex = -1;
                        //文本框中的内容变成高亮节点的内容
                        if (temp.indexOf("; ") >= 0) {
                            var tempVal = temp.substring(0, tempid);
                            data.value = tempVal + comText + "; ";

                        } else {
                            data.value = comText + "; ";
                        }
//                        data.value = comText;
                    })
                    if (carlist.length > 0) {    //如果返回值有内容就显示出来
                        auto.show();
                    } else {               //服务器端无内容返回 那么隐藏弹出框
                        auto.hide();
                        //弹出框隐藏的同时,高亮节点索引值也变成-1
                        highlightindex = -1;
                    }
                }
            }
            //点击页面隐藏自动补全提示框
            document.onclick = function (e) {
                var e = e ? e : window.event;
                var tar = e.srcElement || e.target;
                if (tar.id != "search") {
                    if (auto.is(":visible")) {
                        auto.css("display", "none")
                    }
                }
            }
        }
        /**
         * 当光标聚焦此处时
         * @param data  当前DOM对象
         */
        function onFocus(data) {
            if ($(data).val() == "") {
                var value = $(data).nextAll("input").val();
                var test_list = eval("("+value+")");
                AutoComplete($(data).nextAll("div"), data, test_list);
            }
        }
        /**
         * 监听键盘松开
         * @param input DOM对象
         */
        function onKeyUp(data) {
            var value = $(data).nextAll("input").val();
            var test_list = eval("("+value+")");
            AutoComplete($(data).nextAll("div"), data, test_list);
        }



        /**
         * 根据光标所在位置选中部分文字
         * @param input DOM对象
         */
        function getComponentValue(data) {
            tx = data;
            te = new TextareaEditor(tx);
            var valuetemp = data.value;
            if (valuetemp === '') {
                return;
            }
            var begin;
            var end;

            var pos = te.getSelection();
            var temp = pos.selectionStart;
            if (temp != 0) {
                if (temp == valuetemp.length) {
                    return;
                }
            }
            for (var i = temp; i >= 0; i--) {
                if (i == 0 || valuetemp.charAt(i - 1) === ' ') {
                    begin = i;
                    break;
                }
            }
            for (var i = temp; i <= valuetemp.length; i++) {

                if (valuetemp.charAt(i) === ' ') {
                    end = i + 1;
                    break;
                }
            }
            te.setSelectionRange(begin, end);

        }
        /**
         * 监听键盘按下的哪个键
         * @param data DOM对象
         * @param 事件
         */
        function getKey(data, evt) {
            tx = data;
            te = new TextareaEditor(tx);
            var evt = window.event || evt;
            if (evt.keyCode == 13 || evt.keyCode == 108 || evt.keyCode == 32 || evt.keyCode == 186) {
                te.insertData("; ");
                evt.keyCode = 0;
                evt.returnValue = false;
            }
        }
        /**
         * 获取光标在input中的位置
         * @param input DOM对象
         * @returns {Object} 位置坐标
         */
        function getPosition(input) {
            var pos = 0;
            if (document.selection) {
                input.focus();
                var selection = document.selection.createRange();
                selection.moveStart('character', -input.value.length);
                pos = selection.text.length;
            }
            else if (input.selectionStart || input.selectionStart == '0')
                pos = input.selectionStart;
            return pos;
        }
        /**
         * 获取dom对象在窗口的位置
         * @param data  DOM对象
         * @returns {Object}  json对象,包含DOM的坐标信息
         */
        function getLablePosition(data) {
            var t = data.offsetTop;
            var l = data.offsetLeft;
            var h = data.offsetHeight;
            var w = data.offsetWidth;
            while (data = data.offsetParent) {
                t += data.offsetTop;
                l += data.offsetLeft;
            }
            var point = eval("({x:" + l + ",y:" + t + ",h:" + h + ",w:" + w + "})");
            return point;
        }
    </script>
</head>
<body>
<input type="button" value="afdsafdsagsdfg"/>
<input type="text" id="stringInput" onkeyup="onKeyUp(this)" onclick="getComponentValue(this)" onkeydown="getKey(this)"/>
<input type="hidden"  value ='["小张", "小苏", "小妹妹", "老奶奶", "大鹏", "大明", "你好", "hello", "hi"]'/>
<div id="auto_div">
</div>

</body>
</html>

textarea-editor.js文件如下:

(function() {

    function log(s) {
        return;
        if (window.console)
            console.log(s);
    }

    var OLD_IE = !window.getSelection,IE = window.ActiveXObject;

    /**
     * author:yiminghe@gmail.com
     * @refer:http://yiminghe.javaeye.com/blog/508999
     * @param textarea
     */
    function TextareaEditor(textarea) {

        this.textarea = textarea;
        if (IE) {
            var savedRange;
            textarea.onmousedown
                //onfocus 也要存储,如果直接外部设置selection,则也要讲设置后产生的range存起来
                = textarea.onfocus
                = textarea.onmouseup
                = textarea.onkeydown
                = textarea.onkeyup
                = function() {
                var r = document.selection.createRange();
                //当从 console 过来点击页面时,textarea focus 事件被触发但是范围却不是textarea!
                if (r.parentElement() == textarea) savedRange = r;
                log("savedRange : " + event.type + " : " + r.parentElement().nodeName);
            };
            textarea.onfocusin = function() {
                var r = document.selection.createRange();
                log("onfocusin" + " : " + r.parentElement().nodeName);
                //log(document.activeElement.outerHTML);;
                savedRange && savedRange.select();
            };
            textarea.onblur = function() {
                log("blur");
            };

            textarea.onfocusout = function() {
                log("onfocusout");
                return;
                savedRange = document.selection.createRange();
                log("focusout " + " : " + savedRange.parentElement().outerHTML);
                log(document.activeElement.outerHTML);
            }
        }
    }

    TextareaEditor.prototype = {
        constructor:TextareaEditor,
        getSelection:OLD_IE ? function() {

            var textarea = this.textarea;
            alert(textarea);
            textarea.focus();
            var pos = {},
                i,
                range = document.selection.createRange();
            //parentElement : 获取给定文本范围的父元素。
            if (textarea != range.parentElement()) {
                log(range.parentElement().outerHTML);
                return;
            }
            var range_all = document.body.createTextRange();
            //开始和结束的位置范围包含给定元素中的文本。
            range_all.moveToElementText(textarea);

            for (var sel_start = 0;
                 range_all.compareEndPoints('StartToStart', range) < 0;
                 sel_start++) {
                //每次越过了 \r\n,text.value里 \r\n 算两个
                range_all.moveStart('character', 1);
            }
 
            for (i = 0;
                 i <= sel_start;
                 i++) {
                if (textarea.value.charAt(i) == '\n') {
                    sel_start++;
                }
            }
            pos.selectionStart = sel_start;
            // create a selection of the whole textarea
            range_all = document.body.createTextRange();
            range_all.moveToElementText(textarea);
            // calculate selection end point by moving beginning of range_all to end of range
            var flag = 0;
            for (var sel_end = 0;
                 (flag = range_all.compareEndPoints('StartToEnd', range)) < 0;
                 sel_end++) {

                if (textarea.value.charAt(sel_end) == '\n') {
                    sel_end++;
                }
                range_all.moveStart('character', 1);
            }
            //光标不可能停在\r,\n之间
            if (textarea.value.charAt(sel_end) == '\n') {
                sel_end++;
            }
            pos.selectionEnd = sel_end;
            // get selected and surrounding text
            return pos;
        } : function() {
            var textarea = this.textarea;
            textarea.focus();
            return {
                selectionStart:textarea.selectionStart,
                selectionEnd:textarea.selectionEnd
            };
        },
        setSelectionRange:OLD_IE ? function(start, end) {
            log("setSelectionRange start");
            var v = this.textarea.value,range = this.textarea.createTextRange();
            range.collapse(true);
            start = getLengthForRange(v, start);
            end = getLengthForRange(v, end);
            range.moveEnd("character", end);
            range.moveStart("character", start);
            range.select();
            log("setSelectionRange end");
        } : function(start, end) {
            this.textarea.setSelectionRange(start, end);
            this.textarea.focus();
        },
        insertData :OLD_IE ? function(text) {
            var textarea = this.textarea;
            textarea.focus();
            var range = document.selection.createRange();
            range.text = text;
        } : function(text) {
            var textarea = this.textarea,
                value = textarea.value;
            textarea.focus();
            var range = this.getSelection();
            var start = value.substring(0, range.selectionStart);
            var end = value.substring(range.selectionEnd, value.length);
            var sl = textarea.scrollLeft,st = textarea.scrollTop;
            textarea.value = start + text + end;
            textarea.scrollLeft = sl;
            textarea.scrollTop = st;
            var np = start.length + text.length;
            this.setSelectionRange(np, np);
        }
    };
    function getLengthForRange(text, v) {
        return text.substring(0, v).replace(/\r\n/g, "\n").length;
    }

    window.TextareaEditor = TextareaEditor;
})();


上述代码实现的效果如下图所示:

1.输入值时,代码会监听enter键、空格键、;键,当点击这些按键时,会在input中按照既定格式生成如下的格式,方便回显和进行后续处理;

162514_scja_2303434.png



2.当鼠标点击这个输入框中的任何一个字符时,js会将符合上述格式的文字部分选定,如下图:

162937_te0q_2303434.png

当然,选定后,就可以方便的一下子删除部分文字了。

3.当用户输入信息时,给出提示信息

133227_KarC_2303434.png


转载于:https://my.oschina.net/guopengfei/blog/416797

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值