ホームページ > 記事 > ウェブフロントエンド > JS範囲のHTMLドキュメント/テキストコンテンツの選択、ライブラリとアプリケーションの紹介_JavaScriptスキル
例如下面这个模样的例子:
2011-04-12 负责调查切尔诺贝利核事故对人与环境造成影响的俄科学家亚布罗科夫<span class="selected">博士指出,因福岛核电站使用的燃料较切尔诺贝利核电站多,且有反应堆使用</span>了含有高毒性的钚的燃料,因此"福岛核电站事故可能会比切尔诺贝利带来更严重的后果"。
上面选中状态的那些文字就可以转换成Range对象
(下面会详细讲述)。通过Range对象
你可以找到Range
的起始点和结束点,如果你实在有心,还可以删除或是复制这些内容,或是用其他文字替换,甚至是简单的HTML。
上面的例子可以说是最简单的Range对象
的例子,因为其只包含了文字。而实际上,Range对象
也是可以包含HTML代码内容的,例如下面这个示例:
<time>2011-04-12</time> <p>据日本广播协会电视台12日报道,日本经济产业省原子能安全保安院决定将福岛第一核电站核泄漏事故等级提高至7级。这使日本核<span class="selected">泄漏事故等级与苏联切尔诺贝利核电站核泄漏事故等级相同。</p> <p>负责调查切尔诺贝</span>利核事故对人与环境造成影响的俄科学家亚布罗科夫博士指出,因福岛核电站使用的燃料较切尔诺贝利核电站多,且有反应堆使用了含有高毒性的钚的燃料,因此"福岛核电站事故可能会比切尔诺贝利带来更严重的后果"。</p>
同样的,Range对象
被创建,且包含HTML,现在的问题是选择的内容正好跨过了楚河和汉界(跨标签),如果就单纯的论选择的内容的话,应该如下:
泄漏事故等级与苏联切尔诺贝利核电站核泄漏事故等级相同。</p> <p>负责调查切尔诺贝
显然,上面的HTML属于1级残废,基本无效。然而幸运的是,所有的浏览器都会自动调整HTML片段使其有效,就像变成下面这样:
泄漏事故等级与苏联切尔诺贝利核电站核泄漏事故等级相同。</p> <p>负责调查切尔诺贝
可以看到,浏览器自动补全了一定数目的HTML来让Range
有效。如果你复制或是移动Range
,你所复制或移动的HTML内容一定是有效的。
在真正操刀JavaScript之前我们需要大致知道Range对象
的浏览器兼容性情况。实际上,问题是比较麻烦的,因为至少有3种类似Range对象
,且你有必要全部理解。先展示详细的兼容性情况表:
支持:不支持:部分支持:
Explorer 6/7 | Firefox 2 | Safari 1.3 | Opera 9 | |
---|---|---|---|---|
cloneContents() | ||||
cloneRange() | ||||
collapse() | tbd | tbd | tbd | tbd |
collapsed | ||||
commonAncestorContainer | ||||
compareBoundaryPoints() | ||||
comparePoint() – Mozilla 扩展 | ||||
createContextualFragment() – Mozilla 扩展 | ||||
deleteContents() | ||||
detach() | ||||
endContainer | ||||
endOffset | ||||
extractContents() | ||||
insertNode() | ||||
isPointInRange() – Mozilla 扩展 | ||||
selectNode() | ||||
selectNodeContents() | ||||
setEnd() | ||||
setEndAfter() | ||||
setEndBefore() | ||||
setStart() | ||||
setStartAfter() | ||||
setStartBefore() | ||||
startContainer | ||||
startOffset | ||||
surroundContents() |
说明:cloneContents()
的用法类似docFrag = rangeObject.cloneContents()
,Range对象
内容被克隆同时被添加到文档片段上,并返回自身。但是在Safari下有个问题,即如果选择范围是空,将会返回null
而不是空的文档片段。可以通过类似docFrag = rangeObject.cloneContents() || document.createDocumentFragment()
这样的代码修复。
deleteContents()
处,Range
内容会被永久删除,无返回值。
endContainer
指用户选择内容结尾处的容器节点。通常是文本节点。
extractContents()
用法docFrag = rangeObject.extractContents()
。从DOM树上剪切Range对象
并返回文档片段。该片段可以粘贴到页面上。
startContainer
指用户选择内容起始处的容器节点。通常是文本节点。
startOffset
在Opera浏览器下,在选择内容为空的时候返回0
。
Explorer 6/7 | Firefox 2 | Safari 1.3 | Opera 9 | |
---|---|---|---|---|
addRange() | ||||
anchorNode | ||||
anchorOffset | ||||
collapse() | tbd | tbd | tbd | tbd |
collapseToEnd() | ||||
collapseToStart() | ||||
containsNode() | ||||
deleteFromDocument() | ||||
extend() | ||||
focusNode | ||||
focusOffset | ||||
getRangeAt() | ||||
isCollapsed | ||||
rangeCount | ||||
removeAllRanges() | ||||
removeRange() | ||||
selectAllChildren() | ||||
selectionLanguageChange() |
说明:anchorNode
用法为userSelection.anchorNode
。指用户选择内容起始处的容器节点。通常是文本节点。
anchorNode
在Opera浏览器下,在选择内容为空的时候返回0
。
focusNode
用法为userSelection.focusNode
。指用户选择内容结尾处的容器节点。通常是文本节点。
focusOffset
在Opera浏览器下,在选择内容为空的时候返回0
。
getRangeAt()
用法为rangeObject = userSelection.getRangeAt(0),作用是将
Mozilla Selection
转换为W3C Range
。
Explorer 6/7 | Firefox 2 | Safari 1.3 | Opera 9 | |
---|---|---|---|---|
boundingHeight | ||||
boundingLeft | ||||
boundingTop | ||||
boundingWidth | ||||
collapse() | tbd | tbd | tbd | tbd |
compareEndPoints() | ||||
duplicate() | ||||
expand() | ||||
findText() | ||||
htmlText | ||||
move() | ||||
moveEnd() | ||||
moveStart() | ||||
moveToElementText() | ||||
moveToPoint() | ||||
offsetLeft | ||||
offsetTop | ||||
parentElement() | ||||
pasteHTML() | ||||
scrollIntoView() | ||||
select() | ||||
text |
说明:htmlText
用法为htmlString = userSelection.htmlText
。返回字符串,为TextRange
的HTML内容,相当于innerHTML
。只读。
pasteHTML()
,当粘贴HTML到一个文本节点时,该文本节点自动分隔。
text
用法为string = userSelection.text
。返回字符串,为TextRange
的文本内容,相当于innerText
。可读/写。
Explorer 6/7 | Firefox 2 | Safari 1.3 | Opera 9 | |
---|---|---|---|---|
W3C Range | ||||
Mozilla Selection | ||||
Microsoft Text Range |
手順:
W3C Range对象
が唯一の正式な指定です。基本的に、Range
を DOM を含むドキュメントフラグメントとして扱います。
Mozilla Selection对象
は多少冗長であり、Netscape 4 との下位互換性のために存在します。これは W3C Range对象
に似ており、やはり DOM ツリーに基づいています。
Microsoft Text Range对象
Guo Degang と Xuan Bin の違いは、文字列に基づいているため、上記の 2 つです。実際、Text Range
に含まれる文字列が一度に DOM ノードにジャンプすることは困難です。 一般に、Mozilla Selection对象
は単なる混乱にすぎません。唯一の優れている点は、ユーザーが選択したコンテンツを直接完全な Range对象
に変換できることと、いくつかの追加メソッドまたは属性が Netscape 4 と下位互換性があることです。 。しかし残念ながら、IE 以外の他のブラウザはこの Selection对象
をサポートしています。
義母の説明は必要ありません。関連するコードを見てください:
男性は、たとえ50歳であっても、26歳以上でまだ結婚していない女性には決して触れるべきではありません。彼女は離婚したり、死別したりする可能性がありますが、未婚であることはできません。 26歳を過ぎても結婚していない場合、この種の女性は通常、精神的に異常があるか、そうでなければ深刻な問題を抱えています。市場が間違いを犯すことはほとんどありません。たとえ間違っても宝を拾える確率は非常に低いです。
結婚市場の将来の変化は非常に興味深い問題であり、本土経済の将来の動向にも決定的な影響を与えるでしょう。産業の分布と経済全体の効率。
ノードから始まり、最初の
ノードのテキスト オフセット値は 8 であり、
源代码有些高度,为了节约篇幅,这里就不展示出来了,您可以在demo页面中看到完整的CSS/HTML/JS代码。不过JS部分半封装,您要是有兴趣可以在外面包裹一个函数使其插件化,我是懒得再去折腾了。
对于Range
相关的知识即使到现在都是半生不熟的,所以文章的内容更多的算是翻译性质的内容。自己并没有从深入理解的基础上很浅显地剖析相关知识点,文章很多地方会显得不怎么通俗易懂。
文中多展示的Range
等兼容性表格的数据都是N年前的,还是Safari 1.3时代的数据,老的牙都掉了,实用价值大打折扣,不过可以告知的是先前现代浏览器所不支持的个别属性现早就支持了。
跌跌撞撞,滚滚爬爬。文章难免有表述不准确的地方,欢迎指正。也欢迎提交相关的脚本的bug。
Original article, please indicate when reprinting it from Zhang Xinxu-Xin Space-Xin Life