JS获得textarea的鼠标位置和光标定位在指定位置(IE8/FF)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
        <script type="text/javascript">
            //实现获取焦点位置信息基本功能
            function getOffsetPointer(_mOffset) {
                if (document.selection) {
                    var OffsetObject = new Object();
                    var _allText = _mOffset.value; //输入框的所有值
                    _mOffset.focus(); //输入框获得焦点
                    var s = _mOffset.scrollTop; //获得滚动条的位置
                    var _rOffset = document.selection.createRange(); //创建文档选择对象根据当前文字选择返回 TextRange 对象
                    var _tOffset = _mOffset.createTextRange(); //创建输入框文本对象
                    _tOffset.collapse(true); //将光标移到头
                    _tOffset.select(); //显示光标
                    var _nOffset = document.selection.createRange(); //为新的光标位置创建文档选择对象
                    //在这里主要介绍下TextRange对象的setEndPoint方法和compareEndPoints方法
                    //先介绍setEndPoint("[way]",oRange)方法:将当前范围的开始或结束点移动到oRange范围的开
                    //始或者结束点
                    //该方法有两个参数:[way]表示将当前范围以何种方式移动到oRange范围,有四种方式:
                    //StartToStart将当前开始位置移动到oRange的开始位置,
                    //StartToEnd将当前范围开始位置移动到oRange的结束位置,EndToStart将当前结束位置移动到
                    //oRange的开始位置,EndToEnd将当前范围的结束位置
                    //移动到oRange的结束位置,oRange该对象也是TextRange,oRange的开始和结束位置代表要移动到
                    //的目标位置
                    _rOffset.setEndPoint("StartToStart", _nOffset); //在以前的文档选择对象和新的对象之间创建对象
                    var _leftText = _rOffset.text; //获得文档选择对象的文本(从鼠标焦点到文档开头的文本)
                    var leFTPos = _leftText.length; //文档开头到鼠标焦点的文本长度
                    var _rightText = _allText.substring(leFTPos); //获取鼠标焦点到文档结束的文本
                    alert(leFTPos);
                    OffsetObject.length = leFTPos;
                    OffsetObject.scrollTop = s;
                    OffsetObject.leftValue = _leftText;
                    OffsetObject.rightValue = _rightText;

                    return leFTPos;
                } else {
                    alert(_mOffset.selectionStart);
                    return _mOffset.selectionStart;
                }
            }

            function dingwei(obj) {
                if (document.selection) {
                    var a = document.getElementById("t2").createTextRange();
                    a.moveStart('character', 3); //将开始点向前移动三个位置(每个位置就是一个字符)
                    a.collapse(true);
                    a.select();
                } else {
                    var a = document.getElementById("t2");
                    a.selectionStart = 3;
                    a.focus();
                }
            }
        </script>
    </head>
    
    <body>
        <input type="text" value="HELLO jb51" style="display:block">
        <textarea rows="6" id="t2" cols="60" οnmοuseup="getOffsetPointer(this)">
            jb51 HELLO!
        </textarea>
        <button οnclick="dingwei()" />
    </body>

</html>
本人声明:沐海(http://my.oschina.net/mahaisong) 以上文章是经过本人设计实践和阅读其他文档得出。如果需要探讨或指教可以留言!欢迎交流!



第二版: 修改后,可以定位带有换行符号与删除功能。

删除功能不赘述,通过JQUERY 进行绑定keyup事件。对于不同的event.code进行操作即可。

如果是删除,则重新调用一下这个方法即可。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
        <script type="text/javascript">
            //实现获取焦点位置信息基本功能
            function getOffsetPointer()
            {
               var _mOffset=document.getElementById("t2");
                if (document.selection) {
                    var OffsetObject = new Object();
                    var _allText = _mOffset.value; //输入框的所有值
                    _mOffset.focus(); //输入框获得焦点
                    var s = _mOffset.scrollTop; //获得滚动条的位置
                    var _rOffset = document.selection.createRange(); //根据当前文字选择返回 TextRange 对象文档选择对象
                    var _tOffset = _mOffset.createTextRange(); //创建输入框文本对象--整体
                    _tOffset.collapse(true); //将光标移到头
                    _tOffset.select(); //显示光标,整体选中
                    var _nOffset = document.selection.createRange(); //鼠标选中textarea的左上位置。
                    _rOffset.setEndPoint("StartToStart", _nOffset); //把原本选中的范围的开始位置拉伸到textarea的开始位置。
                    var _leftText = _rOffset.text.replace(/\r\n/g,''); //获得文档选择对象的文本(从鼠标焦点到文档开头的文本)
                    alert(_rOffset.text);
                    var leFTPos = _leftText.length; //文档开头到鼠标焦点的文本长度
                    var _rightText = _allText.substring(leFTPos); //获取鼠标焦点到文档结束的文本
                    alert(leFTPos);
                    OffsetObject.length = leFTPos;
                    OffsetObject.scrollTop = s;
                    OffsetObject.leftValue = _leftText;
                    OffsetObject.rightValue = _rightText;
                    
                    //var n = document.getElementById("t2").value.match(/\r\n/g)||[];
                    //alert(n.length);
                    //_tOffset.scrollTop = s;
                    //_tOffset.moveStart('character', leFTPos+parseInt(n.length)); //将开始点移动到位置。  光标还在原位置。 位置计算好几个\R\N,加上
                    //_tOffset.collapse(true);
                    //_tOffset.select();
                    return leFTPos;
                } else {
                    alert(_mOffset.selectionStart);
                    return _mOffset.selectionStart;
                }
            }

            function dingwei(leFTPos,s) {
                if (document.selection) {
                    var a = document.getElementById("t2").createTextRange();
                    var n = document.getElementById("t2").value.match(/\r\n/g)||[];
                    a.scrollTop = s;
                    a.moveStart('character', leFTPos+parseInt(n.length)); //将开始点向前移动三个位置(每个位置就是一个字符)
                    a.collapse(true);
                    a.select();
                } else {
                    var a = document.getElementById("t2");
                    a.selectionStart = leFTPos;
                    a.focus();
                }
            }
        </script>
    </head>
    
    <body>
        <input type="text" value="HELLO jb51" style="display:block">
        <textarea rows="6" id="t2" cols="60" οnmοuseup="getOffsetPointer()" >
jb51 HELLO!
        </textarea>
        <button οnclick="dingwei()" />
    </body>

</html>


第三版:

改进为每次需要做文本处理时再调用当前光标。提高效率。

AJAX传递时,通过onclientclick与onclick结合的两种方式。得到当前的文本的光标位置。

在光标位置中插入文本,并根本要插入的文本类型与光标值计算输出后的光标位置。

调用前台JS的方法。注入。  定位光标位置。



建议treeview还需要做JS的doPostBack的操作。


改成:
可以每次操作都记录。然后存入一个隐藏域。
回发时,后台设置 textarea值, 设置隐藏域值,调用前台定位JS光标。

       var IDS;
              function onReady() {
                  IDS = {
                      txtleFTPos: '<%= leFTPos.ClientID %>',
                      textscrollTop: '<%= scrollTop.ClientID %>',
                      textExpressValue: '<%= ExpressValue.ClientID %>'
                       };

                  jQuery("#" + IDS.textExpressValue).keyup(function () { getOffsetPointer(IDS.textExpressValue);}).mouseup(function () { getOffsetPointer(IDS.textExpressValue); });

             //实现获取焦点位置信息基本功能
             function getOffsetPointer(id) {
                 var _mOffset = document.getElementById(id);
                 if (document.selection) {
                     var _allText = _mOffset.value; //输入框的所有值
                     _mOffset.focus(); //输入框获得焦点
                     var s = _mOffset.scrollTop; //获得滚动条的位置
                     var _rOffset = document.selection.createRange(); //根据当前文字选择返回 TextRange 对象文档选择对象
                     var saverset = document.selection.createRange();
                     var rlength = _rOffset.text.length;
                     var _tOffset = _mOffset.createTextRange(); //创建输入框文本对象--整体
                     _tOffset.collapse(true); //将光标移到头
                     _tOffset.select(); //显示光标,整体选中
                     var _nOffset = document.selection.createRange(); //鼠标选中textarea的左上位置。
                     _rOffset.setEndPoint("StartToStart", _nOffset); //把原本选中的范围的开始位置拉伸到textarea的开始位置。
                     var n = _rOffset.text.match(/\r\n/g) || [];
                     var _leftText = _rOffset.text.replace(/\r\n/g, ''); //获得文档选择对象的文本(从鼠标焦点到文档开头的文本)
                     var leFTPos = parseInt(_leftText.length)+parseInt(n.length); //文档开头到鼠标焦点的文本长度
                     var _rightText = _allText.substring(leFTPos); //获取鼠标焦点到文档结束的文本
                     if (!(rlength > 0)) //非选中文字
                     {
                         dingwei(leFTPos, s, IDS.textExpressValue);
                     } else //选中文字的保持选中选区的方法。
                     {
                         saverset.select();
                     }
                     jQuery("#" + IDS.txtleFTPos).val(leFTPos);
                     jQuery("#" + IDS.textscrollTop).val(s);
                     return leFTPos;
                 } else {
                     jQuery("#" + IDS.txtleFTPos).val(_mOffset.selectionStart);
                     jQuery("#" + IDS.textscrollTop).val("-1");
                     return _mOffset.selectionStart;
                 }
             }

             function dingwei(leFTPos, s, id) {
                 if (document.selection) {
                     var a = document.getElementById(id).createTextRange();
                     //var n = document.getElementById(id).value.match(/\r\n/g) || [];
                     a.scrollTop = s;
                     //a.moveStart('character', leFTPos + parseInt(n.length)); //将开始点向前移动三个位置(每个位置就是一个字符)
                     a.moveStart('character', leFTPos);
                     a.collapse(true);
                     a.select();
                 } else {
                     var a = document.getElementById(id);
                     a.selectionStart = leFTPos;
                     a.focus();
                 }
             }
         }

第三版实现。


后台插入, 无法得到具体的换行。 因为不知道本行的长度,以及加入文本后是否换行。

将导致换行后, 表达式定位文本少一位, 无法继续输入内容。


解决方案2种: 一种,设置textarea的列,规定每一行多少字。 然后得到当前行的文本长度。

                    第二种,输入即缩进。

                得到当前的长度则可以实现换行。

                后台输入:换行  两个字符缩进 输出 \r\n 然后是想要的文本。

               因为我知道自己的文本是不会超过的。

                可是换行是不是太多了。 



更棒的方法思路:


因为记录了原本的光标位置。  通过新的光标位置与 原本的之间的文本查看是否有插入\r\n, 有则把新的光标位置+1即可。

                //隐藏域 位置长度(用于插入,计算新的位置 +回传)+ 滚动条位置(回传)。
                //输入的长度是否换行? 通过返回的JS的新的位置与老位置之间是否有换行来决定新的位置是否加1(+换行数量),滚动条位置要设置为最新的(用于自动滚动位置)。

哈哈。

经测试,textarea中如果利用后台拼接字符串赋值过长。即使通过前台的textarea展示为有换行。但是其本身的

text里面并没有\R\N这样的换行符,只是过长后的textarea自动显示换行。


又省了力气了。

现在只要先设置滚动条位置,然后把光标定位即可。


本人声明:沐海(http://my.oschina.net/mahaisong) 以上文章是经过本人设计实践和阅读其他文档得出。如果需要探讨或指教可以留言!欢迎交流!

转载于:https://my.oschina.net/mahaisong/blog/146193

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值