刚和同事讨论了一个很有趣的问题,有个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.
Mark
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 태그를 제거한 다음 일반 규칙을 사용하여 이전 parent.innerHTML에서 이 html 코드의 위치를 결정할 수 있습니다. 알겠습니다. 오프셋을 판단할 필요는 없습니다. 시작, 끝 노드 및 오프셋을 얻을 수 있습니다
이런 식으로 IE6, 7, 8에서는 사용자가 선택한 콘텐츠의 시작, 끝 노드와 오프셋을 기록할 수 있습니다^_^
============================================== == ==============
이 작업을 수행할 때의 유일한 단점은 단일 문자나 반복되는 단어의 경우 거리를 판단하여 선택된 문자인지 확인하려면 여전히 CSS의 offsetLeft 속성을 사용해야 한다는 것입니다. 나쁜 조언이 있나요
============================================= === ================
그러던 오늘 아침, 우리는 offsetTop과 left를 사용하지 않고 단일 노드 내에서 반복되는 문자의 오프셋 문제를 해결하기 위해 번쩍이는 영감을 얻었고 아이디어를 교환했습니다.
코드는 다음과 같습니다
<script> <br>function mark() { <br>var Selection=document.selection.createRange() <br>if(selection.text.length==0); >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>document.body.onmouseup=mark; <br>//document.body.onmousedown=mark; <br>} <br></script> /head>
飞飞飞飞飞a a a 🎜> 오프셋을 계산하려면 노드 내부의 문자 1개를 연속적으로 아래쪽 또는 위쪽으로 이동하는 방법을 사용하는 것이 좋습니다. 단일 요소 내 핫 영역의 경우 해당 parentElement()가 범위를 벗어나면 자체적으로 반환되기 때문입니다. 다중 노드인 경우 반환된 parentNode는 자체 상위 노드가 됩니다. 이 변경 사항을 사용하여 노드 텍스트의 끝으로 이동할지 여부를 결정할 수 있습니다. ^_^이 방법으로 오프셋을 계산할 수 있습니다
요약하면 htmlText 속성은 다중 노드 선택 시 핫스팟 위치 지정 문제를 해결할 수 있습니다. 단일 노드 내부 복제 문자는 기사의 마지막 코드 부분을 통해 해결할 수 있으므로 IE에서는 커서가 선택된 위치를 기록하고 재현하는 방법이 완벽합니다 ^_^
========== ==================================
키시그룹에 가서 물어보니 Chengyu가 위치를 얻기 위해 완전히 호환되는 코드를 만든 것으로 밝혀졌습니다. 링크는 다음과 같습니다
http://www.jb51.net/article/ 28120.htm
코드:
http://lite-ext.googlecode.com/svn/trunk/lite-ext/playground/range/ie.html
성명: 본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.