zoukankan      html  css  js  c++  java
  • 讨厌的文本选区

    喜欢直奔主题的同学可略过介绍和分析,直接copy去吧,代码都是function式的,看效果可以直接以 fun.call(element,arg....) 调用。

    Ctrl+End直奔页尾吧~

    文本选区的操作可能是WEB前端的一个比较郁闷的地方。

    我想有时候想自己写个编辑器,设置编辑器中的文本为特定的样式就是一个很大的难点。

    看书上写的也是云里雾里的,于是自己动手写吧,资料还是找官方的。

    首先我啥也不知道。列出一个我需要的功能。

    1. 获得我选中的文本值
    2. 获得当前的位置
    3. 替换、删除选中的值
    4. 在固定的位置插入值
    5. 设置光标所在的位置
    6. 选中一个段文本

    首先开始百度谷歌,不过情况都不太好,不给力。代码都含糊不清。但是搜索到一个有用的信息: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>

  • 相关阅读:
    九度OJ 1035:找出直系亲属(二叉树)
    while 循环的理解
    while 循环的理解
    count 变量的使用
    count 变量的使用
    数据结构与算法的实现 —— 结点定义与数据结构的选择
    数据结构与算法的实现 —— 结点定义与数据结构的选择
    最小生成树(MST,minimum spanning tree)
    最小生成树(MST,minimum spanning tree)
    Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
  • 原文地址:https://www.cnblogs.com/webooxx/p/1981669.html
Copyright © 2011-2022 走看看