网页特效 获取textarea 元素的光标位置代码
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=gb2312" />
<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">
/**
* cursorposition object
*
* created by blank zheng on 2010/11/12.
* copyright (c) 2010 planabc.net. all rights reserved.
*
* the copyrights embodied in the content of this file are licensed under the bsd (revised) open source license.
*/
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(),
// don't: or = textarea.createtextrange()
or = document.body.createtextrange();
or.movetoelementtext(textarea);
rangedata.text = os.text;
rangedata.bookmark = os.getbookmark();
// object.movestart(sunit [, icount])
// return value: integer that returns the number of units moved.
for (i = 0; or.compareendpoints('starttostart', os) < 0 && os.movestart("character", -1) !== 0; i ++) {
// why? you can alert(textarea.value.length)
if (textarea.value.charat(i) == 'n') {
i ++;
}
}
rangedata.start = i;
rangedata.end = rangedata.text.length + rangedata.start;
if(!rangedata.text) {
}
}
return rangedata;
},
set: function (textarea, rangedata) {
var or;
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();
/*// fixbug : ues movetobookmark()
// in ie, if cursor position at the end of textarea, the setcursorposition function don't work
if(textarea.value.length === rangedata.start) {
or.collaps教程e(false)
or.select();
} else {
or.movetobookmark(rangedata.bookmark);
or.select();
}*/
or.movestart('character', rangedata.start);
or.moveend('character', rangedata.end - textarea.value.length);
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;
// fixbug:
// after textarea.values = nvalue, scrolltop value to 0
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(){
//alert(tx.value.length);
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>
首先,我们用 rangedata 对象作为数据存储,并获得焦点:
var rangedata = {start: 0, end: 0, text: "" };textarea.focus();对于非 ie 浏览器获取选区的起始和末尾位置其实非常容易:
rangedata.start= el.selectionstart;rangedata.end = el.selectionend;通过截取我们可以得到光标的选区内容:
rangedata.text = (rangedata.start != rangedata.end) ? el.value.substring(rangedata.start, rangedata.end): "";而对于 ie 浏览器处理起来就比较麻烦了,但我们依旧可以获取到选区:
os = document.selection.createrange();同时还可获取 textarea 元素的选区:
// 为了使 or 与 os 在同一等级上比较,请勿使用:or = textarea.createtextrange()or = document.body.createtextrange();or.movetoelementtext(textarea);如果光标在 textarea 元素内,很自然 os.text 就是我们需要的选区内容:
rangedata.text = os.text;并且我们可以通过 os.getbookmark() 方法获取到选区的位置数据,该位置数据可以通过 movetobookmark() 方法设置回去。
getbookmark: retrieves a bookmark (opaque string) that can be used with movetobookmark to return to the same range.
movetobookmark: moves to a bookmark.
我们用 rangedata.bookmark 来记录该位置数据:
rangedata.bookmark = os.getbookmark();下面是最重要的步骤:我们比较 or 与 os 的选区起始位置(使用 object.compareendpoints(stype, orange) 方法比较),如果 or 的起始位置在 os 之前,我们向前移动 os 的起始位置1个字符(使用 object.movestart(sunit [, icount]) 方法移动),一直当 os 的起始位置在 or 之前停止,移动的位置,则是选区的起始位置。
compareendpoints: compares an end point of a textrange object with an end point of another range.
movestart: changes the start position of the range.
for (i = 0; or.compareendpoints('starttostart', os) < 0 && os.movestart("character", -1) !== 0; i ++) {}rangedata.start = i;但由于在 ie 中,textarea 元素中的所有换行符都占 1 个字符,可以通过 alert(textarea.value.length) 查看,故要对上面的代码做部分处理:
for (i = 0; or.compareendpoints('starttostart', os) < 0 && os.movestart("character", -1) !== 0; i ++) { // why? you can alert(textarea.value.length) if (textarea.value.charat(i) == 'n') { i ++; }}rangedata.start = i;既然得到了选区的起始位置和选区字符串的字符,很自然我们可以计算得到选区的末尾位置:
rangedata.end = rangedata.text.length + rangedata.start;