JavaScript 技巧:Textarea 元素的光标位置

水木兰 · 2018年06月02日 · 439 次阅读

该功能常应用于富文本编辑器的 toolbar 项:点击工具栏上面的某一个按钮,然后在对应的 TextArea 区域进行文本修改操作。比如:加粗、颜色等。

由于需要考虑到各浏览器的兼容性,所以代码中做了一些特殊判断。
特整理了一份代码,备忘于此。

该 Demo 有以下3个功能:

  • 获取 Textarea 元素当前的光标位置
  • 设置回原先的 Textarea 元素的光标位置
  • 在 Textarea 元素的光标位置插入文本

DEMO 代码

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Demo : Textarea 元素的光标位置</title>
<style>
#result {
    font-size:18px;
    line-height:25px;
    padding-left:20px;
}
</style>
</head>

<body>

<h1>Textarea 元素的光标位置</h1>
<ul>
    <li>获取 Textarea 元素当前的光标位置</li>
    <li>设置回原先的 Textarea 元素的光标位置</li>
    <li>在 Textarea 元素的光标位置插入文本</li>
</ul>

<form action="#">
    <textarea id="test" rows="8" cols="50"></textarea>
    <p>
        <input type="button" id="get" value="Get Cursor Position"/>
        <input type="button" id="set" value="Set Cursor Position"/>
        <input type="button" id="add" value="Add Text After Cursor Position"/>
    </p>
</form>

<h2>Textarea Range:</h2>
<div id="result"></div>

<script type="text/javascript">


var cursorPosition = {
    get: function (textarea) {
        var rangeData = {text: "", start: 0, end: 0 };

        if (textarea.setSelectionRange) { // W3C
            textarea.focus();
            rangeData.start= textarea.selectionStart;
            rangeData.end = textarea.selectionEnd;
            rangeData.text = (rangeData.start != rangeData.end) ? textarea.value.substring(rangeData.start, rangeData.end): "";
        } else if (document.selection) { // IE
            textarea.focus();
            var i,
                oS = document.selection.createRange(),
                oR = document.body.createTextRange();
            oR.moveToElementText(textarea);

            rangeData.text = oS.text;
            rangeData.bookmark = oS.getBookmark();

            for (i = 0; oR.compareEndPoints('StartToStart', oS) < 0 && oS.moveStart("character", -1) !== 0; i ++) {

                if (textarea.value.charAt(i) == '\r' ) {
                    i ++;
                }
            }
            rangeData.start = i;
            rangeData.end = rangeData.text.length + rangeData.start;
        }

        return rangeData;
    },

    set: function (textarea, rangeData) {
        var oR, start, end;
        if(!rangeData) {
            alert("You must get cursor position first.")
        }
        textarea.focus();
        if (textarea.setSelectionRange) { // W3C
            textarea.setSelectionRange(rangeData.start, rangeData.end);
        } else if (textarea.createTextRange) { // IE
            oR = textarea.createTextRange();
            if(textarea.value.length === rangeData.start) {
                oR.collapse(false);
                oR.select();
            } else {
                oR.moveToBookmark(rangeData.bookmark);
                oR.select();
            }
        }
    },

    add: function (textarea, rangeData, text) {
        var oValue, nValue, oR, sR, nStart, nEnd, st;
        this.set(textarea, rangeData);

        if (textarea.setSelectionRange) { // W3C
            oValue = textarea.value;
            nValue = oValue.substring(0, rangeData.start) + text + oValue.substring(rangeData.end);
            nStart = nEnd = rangeData.start + text.length;
            st = textarea.scrollTop;
            textarea.value = nValue;
            if(textarea.scrollTop != st) {
                textarea.scrollTop = st;
            }
            textarea.setSelectionRange(nStart, nEnd);
        } else if (textarea.createTextRange) { // IE
            sR = document.selection.createRange();
            sR.text = text;
            sR.setEndPoint('StartToEnd', sR);
            sR.select();
        }
    }
}


var tx=document.getElementById("test"),
    re=document.getElementById("result"),
    pos;

document.getElementById("get").onclick = function(){
    pos = cursorPosition.get(tx);
    re.innerHTML=("<strong>Range :</strong> (" + pos.start + ", " + pos.end + ")<br /><strong>Text :</strong> " + (!pos.text ? '//--': pos.text));
}

document.getElementById("set").onclick = function(){
    cursorPosition.set(tx, pos);
}

document.getElementById("add").onclick = function(){
    cursorPosition.add(tx, pos, input = prompt("你想插入替换的文本:",""));
}
</script>

</body>
</html>
共收到0条回复
暂无任何评论
我要评论
登录之后,才能够回复。如果您还没有帐号,请先注册
小甜饼

在学习上做一眼勤、手勤、脑勤,就可以成为有学问的人。 —— 吴晗