Heim  >  Artikel  >  Web-Frontend  >  IE6,IE7,IE8下使用Javascript记录光标选中范围(已补全)_javascript技巧

IE6,IE7,IE8下使用Javascript记录光标选中范围(已补全)_javascript技巧

WBOY
WBOYOriginal
2016-05-16 18:02:541145Durchsuche

刚和同事讨论了一个很有趣的问题,有个idea,需要记录用户在页面选中的内容,在ff和ie9下有w3c的dom2级事件createRange,这里不再累赘。主要问题是在IE6,7,8只能通过createTextRange选中热区。假如我们知道用户选择开始元素和偏移量,以及结束元素以及偏移量,那么我们可以用下面的例子把用户选择的内容用js给标记起来

复制代码 代码如下:


<script> <BR>function mark() { <BR>var b= document.getElementById ("b"); <BR>var b1= document.getElementById ("b1"); <BR>var b2= document.getElementById ("b2"); <BR>var a1 = document.body.createTextRange(); <BR>a1.moveToElementText(b); <BR>a1.moveStart('character',17); <BR>var a2 = document.body.createTextRange(); <BR>a2.moveToElementText(b1); <BR>a2.moveEnd('character',-2); <BR>a1.setEndPoint ("EndToEnd",a2); <BR>a1.select(); <BR>}</script>


The contents of the source element.

The contents of the source element.

The contents of the source element.




ok,从上面的代码,我们可以知道,在IE6,7,8下,需要关联多个元素的选择时候,我们需要创建两个textRange,一个是开始节点,以及偏移量,还有一个结束节点,以及偏移量,两个textRange用a1.setEndPoint关联

参考文档:http://help.dottoro.com/ljgbbkjf.php

http://msdn.microsoft.com/en-us/library/ms535872%28VS.85%29.aspx

上面是我们知道开始结束位置的情况下,那我们如何知道用户自己选中的热区的开始,结束节点和偏移量呢?

很可惜查了半天,MSDN只有以下几个属性可以利用,

textRange.parentElement返回选中热区的父亲节点,可以帮助我们确定,一个大概的范围

boundingLeft,offsetLeft,可以知道热区的左偏移距离

boundingTop,offsetTop,可以知道热区的上偏移距离

text,选中的文本内容,htmlText选中的html内容

可以没有直接的index…,和开始节点。。。之类

好吧,如果我们要通过位置来算的话,我们可以通过每行的line-height,计算高度,如果是一个节点的话,要计算节点的height,padding,marging,

如果是计算左偏移的话,要计算font-size,margin,padding,letter-space,这样我们通过css的计算,可以得到大致的位置,

然后我们结合text,和htmlText去比对附近的元素的文本内容,可以得到索引的坐标

这样 基本上我们可以确定开始/结束节点,以及偏移量了,

不过这样做的成本也是比较高的,不知道大家还有没有好的办法,或者hacker的方法^_^

==================================================================================

刚才又看了下htmlText方法,有个惊奇的发现,还是上面的例子,htmlText返回如下

 

he source element.

The contents of the source element

可以看到开始节点的tagName,还有选中的内容,可以通过去掉开头结尾的html tag,然后用正则判断取到这段html代码在之前的parent.innerHTML的位置,这样偏移量也就取到了,ok,不需要通过判断offset的方式,我们就可以取到开始,结束节点,以及偏移量了

这样在IE6,7,8下,可以记录用户任意选中的内容的开始、结束节点,以及偏移量了^_^

 =============================================================

只是这样做,还有一个唯一的缺点就是对于单个字符,或者重复出现的单词,还是得通过css的offsetLeft 这样的属性 ,通过判断距离,还确定是否是选中的那个,不知道大家有没好的建议

===============================================================

然后今天早上,今天灵光一现,互发奇想,解决不需要通过offsetTop,left判断单个node内部,重复字符的偏移量问题

代码如下

复制代码 代码如下:


<script> <BR>function mark() { <BR>var selection=document.selection.createRange(); <BR>if(selection.text.length==0){ <BR>return; <BR>} <BR>var textLength=event.srcElement.innerText.length; <BR>var oldSelectionParent=selection.parentElement(); <BR>do{ <BR>selection.moveEnd("character",1); <BR>}while(selection.parentElement()==oldSelectionParent); <BR>selection.moveEnd("character",-1); <BR>alert(textLength - selection.text.length); <BR>} <BR>function load(){ <BR>document.body.onmouseup=mark; <BR>//document.body.onmousedown=mark; <BR>} <BR></script>


飞 a a a a 飞飞飞飞飞a飞 a a a



原理就是利用在一个节点内部,不断偏移1个字符,到底部或者顶部,计算偏移量的方法,因为对于单个元素内的热区,他的parentElement()返回就是他自己,如果跨多个节点,之后,返回的parentNode就是他自己的父节点了,可以通过这个变化,判断,是否移动到该节点文本的尽头。^_^这样就可以计算偏移量了




ok,总结,通过htmlText的属性可以解决多节点选中热区的定位问题,对于单节点内部重复字符,可以通过文中最后一部分代码解决,这样在IE下,记录光标选中位置,和复现的方法就完美了^_^


============================================

去kissy群问了下,原来承玉已经做过全兼容的取位置的代码,链接如下
http://www.jb51.net/article/28120.htm

代码:http://lite-ext.googlecode.com/svn/trunk/lite-ext/playground/range/ie.html

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn