JS脚本获取Div选中文字在整篇文章的起始位置(start)和结束位置(end)

目前我开发的一个PHP系统中需要在div中截取文章被选文字的起始位置的功能。但是很遗憾,google、baidu了很多资料都非常不理想,于是自己深入研究了一下Selection对象,做了个针对IE的版本,相信能帮助需要这类功能的朋友,主要代码如下:

function getSel()
{
    var element = document.getElementById('thediv');
    if( document.selection ){
        var range = document.selection.createRange();
        var stored_range = range.duplicate();
        stored_range.moveToElementText( element );
        stored_range.setEndPoint( 'EndToEnd', range );
        element.selectionStart = stored_range.text.length - range.text.length;
        element.selectionEnd = element.selectionStart + range.text.length;
     }

     alert(element.selectionStart+";"+element.selectionEnd);
}

查看 DEMO 页面

说明:打开Demo页面后,用鼠标选中一段文字或单词,此时会弹出被选中文字在整篇文章中的起始位置。

Annotation Tool 项目Video演示 download  (rar 439kb) 

2009-04-04补充:

关于定位问题,我再补充一下,其实上面的方法不够好,我再提供一个更加简便易行的方法:

// 在得到selection and range的情况下:
var startRangeOffset = range.startOffset;
range.collapse(true);
range.setStart(range.startContainer, startRangeOffset-1);
range.setEnd(range.startContainer, startRangeOffset-1+plenght);

由于firefox的定位或者说是用js根据得到的start和end位置来设置选区,这个功能在textarea中ff实现起来相当容易,但在div等同类容器中进行设置选区就显得有些困难,至少现在google等一些搜索引擎中也没能找到比较好的解决方法,所以我研究了DOM 2的一些函数,得出以上方法可以设置选区,使用js在firefox中设置选取文字的起始位置和结束位置。有点啰嗦,sorry,我解释一下,firefox的dom tree是很正规的,所以如果你使用前面的方法得到起始位置来代替startRangeOffset 变量,会存在这样的问题,当你在一个容器中存在多个node对象的时候,这个时候你使用前面的方法得到起始位置来代替startRangeOffset 变量就是出现一些问题,因为firefox每跳过一个node对象就开始重新计算起始位置。我不能够解释得很清楚,希望大家通过尝试来增强自己的理解,在我的TcEditor项目中我使用了以上方法设定选区或者定位,所谓定位,就是setStart和setEnd设置相同的index即可。OK,Good Luck!!

关于setStart和setEnd函数,大家参考,以上示例代码取自我的一个内部开源项目,不可直接使用,理解之后就知道该怎么使用,Thanks,好好学习一下:

https://developer.mozilla.org/en/DOM/range

引用通告地址: 点击获取引用地址
标签: 脚本
评论: 17 | 引用: 0 | 阅读: 4296 | 打印 | 打包 | 转发
  • 1 
李嘉 [ 2009-03-28 12:12 邮箱 网址 | 回复 | 编辑 删除 ]
这里我再给出一个支持ie&ff的方法:

function GetSelection() {
if (Browser.Engine.trident) { // mootools框架中代表如果是ie则true
        selection = document.selection;
        range = selection.createRange();
        range_text = range.text;
} else {
        selection = window.getSelection();
        range = selection.getRangeAt(0);
        range_text = range.toString();
}
}

function getCaret(id) {
GetSelection();

var selectionStart = 0;
var selectionEnd = 0;
var el = $(id);

if( document.selection ){
        var range2 = document.selection.createRange();
        var stored_range = range2.duplicate();
        stored_range.moveToElementText( el );
        stored_range.setEndPoint( 'EndToEnd', range2 );$('test').innerHTML = stored_range.text;
        selectionStart = stored_range.text.length - range2.text.length;
        selectionEnd = selectionStart + range2.text.length;
} else {
        var endChar = range.toString().length;
        var stored_range = range.cloneRange();
        stored_range.collapse( true );
        stored_range.setStart( el,0 );
        var startChar = stored_range.toString().length + 1;
        endChar = ( endChar + stored_range.toString().length );
        selectionStart = startChar - 1;
        selectionEnd = endChar;
}

return {start: selectionStart, end: selectionEnd};
};

缺点:ie获取焦点起始位置一块会忽略掉换行符\n或 br,所以当你再根据获取到的焦点位置去设置选区的时候会发生问题。我正在研究解决方案。
xiaogang [ 回复于2011-05-30 15:20 | 编辑 删除 ]
该内容只有管理员可见
翱翔 [ 2009-04-03 15:46 | 回复 | 编辑 删除 ]
获取位置后,在firefor上在定位就不好搞啦
翱翔 [ 2009-04-03 15:47 | 回复 | 编辑 删除 ]
有什么方法能让firefor根据位置来定位呢?
李嘉 [ 回复于2009-04-04 14:13 邮箱 网址 | 编辑 删除 ]
可以,我看过你的留言之后,我在文章中进行了一段补充,可以定位firefox的焦点和选区,详细请看2009-04-04补充后的内容,祝你好运。
Java宅男 [ 2009-12-11 15:24 网址 | 回复 | 编辑 删除 ]
Annotation Tool 项目Video演示 download (rar 439kb)

这个项目的源码可否发我一份?chenglu#yeah.net
李嘉 [ 回复于2009-12-11 16:24 邮箱 网址 | 编辑 删除 ]
对不起,项目涉及到客户的机密,所以不能发给你,sorry。
Java宅男 [ 2009-12-11 22:04 网址 | 回复 | 编辑 删除 ]
原来是这样,我的问题有点冒昧哈,但是学到了不少,仍然感谢你。
我是要做一个划词评注的功能,不知道博主可有些许指导?
李嘉 [ 回复于2009-12-12 00:38 邮箱 网址 | 编辑 删除 ]
我想和我的程序应该有些类似,建议用Ajax来做,你要的功能应该不是很复杂,逐步解决以下问题即可:

(1) 获取选中的文字
(2) 给选中文字加上一个span,Ex. <span title="评词语">选中我啦</span>

如果你对DOM比较熟悉应该可以很快做出这个功能。嗯,具体我们可以再讨论。
Java宅男 [ 2009-12-12 10:25 网址 | 回复 | 编辑 删除 ]
感谢回复,Gtalk已加,不知道您是否使用,我是一菜鸟,接触的东西不多,如果有什么关于这个项目的问题,我再回到这个页面提问:)打扰了~嘿嘿
李嘉 [ 回复于2009-12-12 18:16 邮箱 网址 | 编辑 删除 ]
OK, Gtalk用的。有问必答。
Java宅男 [ 2009-12-13 15:27 网址 | 回复 | 编辑 删除 ]
我申请交换链接,我的站pr3.嘿嘿,咋不见动静呢。:)
李嘉 [ 回复于2009-12-13 17:47 邮箱 网址 | 编辑 删除 ]
好的。
墨白 [ 2010-01-03 10:52 网址 | 回复 | 编辑 删除 ]
Annotation Tool
这个里面使用了什么技术?Jquery?还是?
李嘉 [ 回复于2010-01-03 20:05 邮箱 网址 | 编辑 删除 ]
Javascript+Mootools 1.2.
苏苏头 [ 2011-02-28 22:49 网址 | 回复 | 编辑 删除 ]
您好,我给您发了一封邮件请教一些问题,希望能得到解答,谢谢~
李嘉 [ 回复于2011-03-01 00:11 邮箱 网址 | 编辑 删除 ]
已经回复给你,感谢。
  • 1 
发表评论
昵 称: 密 码:
网 址: 邮 箱:
验证码: 验证码图片 选 项:
头 像:
内 容:
  • 粗体
  • 斜体
  • 下划线
  • 插入图像
  • 超链接
  • 电子邮件
  • 插入引用