喜欢直奔主题的同学可略过介绍和分析,直接copy去吧,代码都是function式的,看效果可以直接以 fun.call(element,arg....) 调用。
Ctrl+End直奔页尾吧~
文本选区的操作可能是WEB前端的一个比较郁闷的地方。
我想有时候想自己写个编辑器,设置编辑器中的文本为特定的样式就是一个很大的难点。
看书上写的也是云里雾里的,于是自己动手写吧,资料还是找官方的。
首先我啥也不知道。列出一个我需要的功能。
- 获得我选中的文本值
- 获得当前的位置
- 替换、删除选中的值
- 在固定的位置插入值
- 设置光标所在的位置
- 选中一个段文本
首先开始百度谷歌,不过情况都不太好,不给力。代码都含糊不清。但是搜索到一个有用的信息:IE浏览器的 Range 和非IE浏览器的 Range 实现方式不一致。
搜索到的代码就不列出了。现就最后 的实现代码做分析。
1 // 取得选中的值
2 // 参数
3 // 返回 String:"Range Text"
4 function getRngVal(){
5 if( document.selection &&(document.selection.type=='Text')){
6 // IE处理
7 // document.selection 是IE下特有的在这里侦测了下选中的是否是文本
8 var rng = document.selection.createRange();
9 // 整个文档选取创建了一个 Range 对象,注意不是 TextRange,此时的rng.text是整个页面内所有的文本
10
11 // 如果选取的文本区域不是从当前对象选取的话就返回一个空
12 if (rng.parentElement() != this){
13 return "";
14 }
15 // 否则返回选中的文本段落
16 return document.selection.createRange().text;
17 }
18 // 非IE处理
19 if(this.selectionStart != undefined && this.selectionEnd != undefined) {
20 // 验证下,有没有选中文字
21
22 // 这里比较简单了直接获得选取文字的头尾(所在的字符位置)然后substring返回
23 var s = this.selectionStart;
24 var e = this.selectionEnd;
25 return this.value.substring(s,e);
26 }else {return ""};
27 }
已经可以取得选取的文本的信息了,接下去看下如何获得文本所在的位置,相信看过上面的代码了,非IE浏览器直接获得 this.selectionStart; this.selectionEnd;就可以了。IE呢?
1 // 取得光标位置
2 // 参数
3 // 返回 array :[start,end]
4 function getRngPos(){
5 var pos = [0,0];
6 if(typeof this.selectionStart == 'number'){
7 pos[0] = this.selectionStart;
8 pos[1] = this.selectionEnd;
9 }
10 else{
11 // 曲折的IE
12 var dng = document.selection.createRange();
13 // 如果选中的文本长度为空
14 // 先聚焦到对象中,再去设置选区
15 if(dng.text.length<1){
16 txt.focus();
17 dng = document.selection.createRange();
18 }
19 // 如果选取的文字所在对象不是当前对象
20 // 退
21 if (dng.parentElement() != this){
22 return pos;
23 }
24 var tng = this.createTextRange();
25 var al = tng.text.length;
26 // IE处理光标范围在最后一个总是会报“未指定的错误”,没办法,只好把他拉到 try 中来了
27 try{
28 // 移动选取到光标所在的位置(像素)
29 tng.moveToPoint(dng.offsetLeft,dng.offsetTop);
30 }
31 catch(e){
32 return [al,al];
33 }
34 // IE中,移动选取范围从当前位置到整个字符的长度
35 // 后面是计算了,开始的位置就是,所有字符,剪掉移动后的字符,后的长度
36 // 结束的位置就是,所有字符,剪掉移动后的字符,再加上选取的字符本身的长度
37 tng.moveEnd('character',al);
38 pos[0] = al-tng.text.length;
39 pos[1] = al-tng.text.length+dng.text.length;
40 }
41 return pos;
42 }
设置部分下回再说。 ^_^
页面完整代码
View Code
<!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>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>讨厌的文本选区</title>
<script>
// 取得选中的值
// 参数
// 返回 String:"Range Text"
function getRngVal(){
if( document.selection &&(document.selection.type=='Text')){
var rng = document.selection.createRange();
if (rng.parentElement() != this){
return "";
}
return document.selection.createRange().text;
}
if(this.selectionStart != undefined && this.selectionEnd != undefined) {
var s = this.selectionStart;
var e = this.selectionEnd;
return this.value.substring(s,e);
}else {return ""};
}
// 取得光标位置
// 参数
// 返回 array :[start,end]
function getRngPos(){
var pos = [0,0];
if(typeof this.selectionStart == 'number'){
pos[0] = this.selectionStart;
pos[1] = this.selectionEnd;
}
else{
var dng = document.selection.createRange();
if(dng.text.length<1){
txt.focus();
dng = document.selection.createRange();
}
if (dng.parentElement() != this){
return pos;
}
var tng = this.createTextRange();
var al = tng.text.length;
try{
tng.moveToPoint(dng.offsetLeft,dng.offsetTop);
}
catch(e){
return [al,al];
}
tng.moveEnd('character',al);
pos[0] = al-tng.text.length;
pos[1] = al-tng.text.length+dng.text.length;
}
return pos;
}
// 设置光标位置
// 参数 [start,end] || number == [number,number]
// 返回 String:"Range Text"
function setRngPos(){
var arg = arguments[0];
var pos = [] ;
var txt = '';
typeof arg == 'number' ? pos = [arg,arg] : pos = [arg[0],arg[1]];
if(typeof this.selectionStart== 'number'){
this.selectionStart = pos[0];
this.selectionEnd = pos[1];
txt = this.value.substr(pos[0],pos[1]);
}else{
var rng = this.createTextRange();
rng.move('character',pos[0]);
rng.moveEnd('character',pos[1]-pos[0]);
rng.select();
txt = rng.text;
}
return txt;
}
// 插入值到当前位置
// 参数 位置信息:Array||Number
// 参数 插入的文本信息:String
// 参数 正则模式,如果有这个参数的话,并且第一个参数类型是 array,且 a[0]<a[1]则,这个范围内的值将被按照规则替换。
// 返回 array:[原长,现长]
function setRngVal(){
var pos = typeof arguments[0] == 'number'? [arguments[0],arguments[0]] :arguments[0] ;
var txt = arguments[1] || "" ;
var reg = arguments[2] || false;
var al = this.value.length;
var newtxt = [];
newtxt[0] = this.value.substr(0,pos[0]);
if(reg && pos[0]< pos[1] ){
newtxt[1] = this.value.substr(pos[0],pos[1]).replace(reg, txt);
}else{
newtxt[1] = txt;
}
newtxt[2] = this.value.substr(pos[1],al);
this.value = newtxt.join('');
return [al,this.value.length];
}
</script>
</head>
<body style="font-size:12px;color:#000000;background:#FFF;padding:10px;margin:0px; position:relative">
<h1>讨厌的文本选区</h1>
<table width="100%" border="0" cellpadding="10" cellspacing="1" bgcolor="#000000">
<tr>
<td width="100" bgcolor="#FFFFFF"><textarea name="textfield" cols="99" rows="30" id='txt' >0123.456.789abc.中文.098</textarea></td>
<td bgcolor="#FFFFFF">
<div id="returnvaluetostring" style="80%;height:50px;background:#EEE;border:1px solid #DDD"></div>
<hr />
<p>
<input name="button" type="button" onclick="alertin( getRngVal.call($('txt')) )" value="取得选中的值"/>
<input name="button2" type="button" onclick="alertin( getRngPos.call($('txt')) )" value="取得光标位置"/>
</p>
<hr />
<p>位置0<input type="text" id="pos0" value="1" /></p><p>位置1<input type="text" id="pos1" value="2" /></p>
<p>
<input name="button3" type="button" onclick=" setRngPos.call( $('txt') ,[ parseInt( $('pos0').value ), parseInt( $('pos1').value ) ] ) " value="设置光标位置"/>
</p>
<p><input type="text" id="msg" value="新值" />,可以用函数处理,这里只当字符处理<br />
可选正则("pattern",["flags"])<input type="text" id="reg" value="2,ig" /></p>
<p>
<input name="button4" type="button" onclick="setRngVal.call( $('txt') , [ parseInt( $('pos0').value ), parseInt( $('pos1').value ) ] ,$('msg').value , getreg())" value="插入值到指定位置"/>
</p></td>
</tr>
</table>
<script>
function $(id){return document.getElementById(id)}
function getreg(){
if($('reg').value.length<1){return false};
var re = $('reg').value.split(',');
return new RegExp(re[0],re[1]);
}
function alertin(val){
$('returnvaluetostring').innerText = val.toString();
}
</script>
</body>
</html>