html光标操作,插入文字获取选中文字

html代码:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>
    textrange
</title>
<script type="text/javascript" src="textarea-editor.js">
</script>

</head>
<body>
<form action="a.cgi">
    <textarea id="test" rows="10" cols="50"></textarea>
    <br/>

    <a href='#' id="add" value="得到选择区域" unselectable="off">得到选择区域</a>
    <br/>
    <input id="text" style="width:100px"/>
    <input type="button" id="insert" value="光标处插入文本"/>
    <br/>
    开始位置:<input id="start" style="width:100px"/>
    结束位置:<input id="end" style="width:100px"/>

    <a href='#'
           id="s" value="选择位置" unselectable="off">选择位置</a>
    <br/>
    <a value='获得焦点'
       onclick="tx.focus();return false;"
       href='#'
       unselectable="off"/>获得焦点</a>

</form>
<p>结果:</p>
<div style="border:1px solid red;" id="result"></div>
<script type="text/javascript">
    function $(id) {
        return document.getElementById(id);
    }
    var tx = $("test"),te = new TextareaEditor(tx);
    var re = $("result");
    $("add").onclick = function() {

        var pos = te.getSelection();
        re.innerHTML = ("range : " + pos.selectionStart + " - " + pos.selectionEnd);
        return false;

    }

    $("insert").onclick = function() {
        te.insertData($("text").value);
        return false;
    }

    $("s").onclick = function() {
        te.setSelectionRange(parseInt($("start").value), parseInt($("end").value));
        return false;
    }
</script>
</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;
            textarea.focus();
            var pos = {},
                i,
                range = document.selection.createRange();
            //parentElement : 获取给定文本范围的父元素。
            if (textarea != range.parentElement()) {
                log(range.parentElement().outerHTML);
                return;
            }
            // create a selection of the whole textarea
            var range_all = document.body.createTextRange();
            //moveToElementText    Moves the text range so that
            //the start and end positions of the range encompass the text in the given element.
            range_all.moveToElementText(textarea);
            //alert(range_all.text.length);
            //alert(textarea.value.length);
            // calculate selection start point by moving beginning of range_all to beginning of range
            //看这 : http://msdn.microsoft.com/en-us/library/ms536373%28VS.85%29.aspx
            // Compare the start of the TextRange object with the start of the oRange parameter.
            //
            //StartToEnd
            //   Compare the start of the TextRange object with the end of the oRange parameter.
            //StartToStart
            //   Compare the start of the TextRange object with the start of the oRange parameter.
            //EndToStart
            //   Compare the end of the TextRange object with the start of the oRange parameter.
            //EndToEnd
            //   Compare the end of the TextRange object with the end of the oRange parameter.
            //
            //-1
            //   The end point of the object is further to the left than the end point of oRange.
            //0
            //   The end point of the object is at the same location as the end point of oRange.
            //1
            //   The end point of the object is further to the right than the end point of oRange.
            for (var sel_start = 0;
                 range_all.compareEndPoints('StartToStart', range) < 0;
                 sel_start++) {
                //每次越过了 \r\n,text.value里 \r\n 算两个
                range_all.moveStart('character', 1);
            }
            //debugger
            //alert(sel_start);
            //alert(textarea.value.substring(0,sel_start));
            // get number of line breaks from textarea start to selection start and add them to sel_start
            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);
            //select 附带 focus 效果哦
            //内部应该是:
            //1.focus
            //2.select
            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;
})();