textarea光标位置定位、插入、获取选择文字

微博”@”功能相信每一个玩过微博的人都用过,当你输入”@”字符串时,在光标位置旁边就会生成一个提示框,你可以快速的选取你最近”@”过的人。

不过想要操作textarea可是一件麻烦事。由于获取选中区域的接口属于BOM,不同浏览器下的接口差别很大。

先来看看IE下的接口 document.selection

document.selection

  method

clear : Clears the contents of the selection.

createRange : Creates a TextRange object from the current text selection, or a controlRange collection from a control selection.

createRangeCollection : Creates a TextRange object collection from the current selection.

empty : Cancels the current selection, sets the selection type to none, and sets the item property to null.

  properties

type : Retrieves the type of selection.

typeDetail : Retrieves the name of the selection type.

值得注意的是,从IE11开始不再支持selection对象.请使用getSelection对象.

再来看看FF提供的document.getSelection

document.getSelection

  method

getRangeAt : Returns a range object representing one of the ranges currently selected.

注意,用户用鼠标在同一页面永远都只有一个选择区域,所以一般情况getRangeAt只能接收0这一个参数.但用脚本可以创建多个选择区域(Chrome下通过脚本也只能创建一个选择区域)

collapse(parentNode,offset) : Collapses the current selection to a single point.

压缩选择区域至单个光标(在输入框中)位置

  parentNode:光标将要移动到的目标元素

  offset:光标在目标元素中所在偏移量.这里的偏移量会有两个值”0”和”1”,分别表示parentNode文本的起始位置和结束位置.

extend(parentNode,offset):Moves the focus of the selection to a specified point.

  parentNode:光标将要移动到的目标元素

  offset:光标在目标元素中所在偏移量.这里的偏移量会有两种情况:

    1.目标元素只有textNode.这时offset的值表示光标在字符串中的位置

    2.目标元素含有非textNode子元素.这时offset的值表示光标定位到第offset个元素的末尾.

modify(alert,direction,granularity) : Changes the current selection.

改变选择区域

  alert:声明修改类型(move || extend)

  direction:移动(合并)的方向.可能的值forward,backward,left,right.

  granularity:移动(合并)的单位.可能的值charracter,word,sentence,line,paragraph,lineboundary,sentenceboundary,paragraphboundary,documentboundary.(注意,FF不支持sentence,paragraph,sentenceboundary,paragraphboundary,documentboundary.值得一提的是在被选择内容为中文时,FF不支持”granularity=word“,但在Chrome上能正常使用.)

collapseToStart : Collapses the selection to the start of the first range in the selection.

将选择区域压缩至区域开始的位置

collapseToEnd : Collapses the selection to the end of the last range in the selection.

将选择区域压缩至区域结束的位置

selectAllChildren(parentNode) : Adds all the children of the specified node to the selection.

选择parentNode的所有子节点内容

addRange(range) : A Range object that will be added to the selection.

将指定的区域添加到已选择区域

  range:指定区域range可以通过document.createRange创建,也可以通过getRangeAt从已有区域选择

removeRange(range) : Removes a range from the selection.

从选择区域中删除指定的区域

removeAllRanges : Removes all ranges from the selection.

删除所有选择区域

deleteFromDocument : Deletes the selection’s content from the document.

删除选择区域中的文字(只能删除文字,不会删除DOM元素)

selectionLanguageChangae : Modifies the cursor Bidi level after a change in keyboard direction.

在写这篇文章时,这个方法貌似已经不存在了,但官方文档还保留了这个方法.

toString : Returns a string currently being represented by the selection object, i.e. the currently selected text.

输出当前选择区域文本

containNode(aNode,aPartlyContained) : Indicates if a certain node is part of the selection.

检测某些节点,当它属于选择区域时返回true,否则返回false

  aNode:待检测的节点

  aPartlyContained:检测类型

    1.aPartlyContained=true:当aNode的部分或全部属于选择区域的一部分时,则返回true

    1.aPartlyContained=false:当aNode整个节点属于选择区域的一部分时,则返回true(aNode等于选择区域时也返回false,也就是说aNode必须小于选择区域才会返回true)

  properties

anchorNode : Returns the Node in which the selection begins.

返回选择区域开始位置所在的节点

anchorOffset : Returns a number representing the offset of the selection’s anchor within the anchorNode. If anchorNode is a text node, this is the number of characters within anchorNode preceding the anchor. If anchorNode is an element, this is the number of child nodes of the anchorNode preceding the anchor.

返回选择区域开始的位置.如果选择区域是纯文本,返回选择区域中第一个字符的位置.如果选择区域是元素,返回那些在选择区域前面的同时也属于anchorNode的子节点的个数.

focusNode : Returns the Node in which the selection ends.

返回选择区域结束位置所在的节点

focusOffset : Returns a number representing the offset of the selection’s anchor within the focusNode. If focusNode is a text node, this is the number of characters within focusNode preceding the focus. If focusNode is an element, this is the number of child nodes of the focusNode preceding the focus.

参照anchorOffset

ifCollapsed : Returns a Boolean indicating whether the selection’s start and end points are at the same position.

判断选择区域开始于结束位置是否相同

rangeCount : Returns the number of ranges in the selection.

返回getSelection中的range


/*向输入框当前位置插入字符*/
function InsertString(ele, str){
    var r = null,newstart = 0,tb = ele.nodeType == 1 ? ele : docuemnt.body;
    tb.focus();
    if (document.all){
        r = document.selection.createRange();
        document.selection.empty();
        r.text = str;
        r.collapse();
        r.select();
    }else{
        newstart = tb.selectionStart+str.length;
        tb.value=tb.value.substr(0,tb.selectionStart)+str+tb.value.substring(tb.selectionEnd);
        tb.selectionStart = newstart;
        tb.selectionEnd = newstart;
    }
}
/*获取当前选择区域文字*/
function GetSelection(ele){
    var sel = '',r = null,tb = ele.nodeType == 1 ? ele : docuemnt.body;
    if (document.all){
        r = document.selection.createRange();
        document.selection.empty();
        sel = r.text;
    }else{
        sel = tb.value.substring(tb.selectionStart, tb.selectionEnd);
    }
    return sel;
}
function ShowSelection(ele){
    var sel = GetSelection(ele);
    alert('选中的文本是:'+sel);
}
/*获取光标位置*/
function getAnchor(ele){
    var index = 0,r = null,tb = ele.nodeType == 1 ? ele : document.body;
    if(document.all){
        r = document.selection.createRange();
        tb.focus();
        r.moveStart('character', -tb.value.length); 
        index = r.text.length;    
    }else{
        index = tb.selectionStart
    }
    return index
}

selection的官方文档

getSelection的官方文档