以这段文字为例子。。

<p><b>法国国营铁路公司(SNCF)20日承认,</b>新订购的2000列火车因车体过宽,<strong>无法开进国内许多火车站的站台,从而不得不花大笔资金改造站台。</strong>法国国营铁路公司发言人克里斯托夫·皮耶诺埃尔告诉法国新闻电台:“我们发现问题晚了点。<b>我们承认这一失误并为此承担责任。”</b></p>

一个P标签包含了文字节点以及其他几个标签,标签中包含了文字节点。

selection 对象有一下几个属性:(以下都为chrome下单测的结果,firefox,IE另说)

  • anchorNode:anchorNode为selection对象的起点Node,假如选中的文字为“新订购的2000列火”,那么anchorNode就为“ 新订购的2000列火车因车体过宽”, ”这个文字节点。anchorNode还有几个子属性,我选出有用的有这么几个:length:这个节点的文字个数、nextSibling:这个文字节点的下一个同级节点,这里为 Strong标签、previousSibling:这个文字节点的前一个标签,这里是 B标签、textContent:这个选中的文字节点的全部文字,全部文字就是“ 新订购的2000列火车因车体过宽, ”即便只选择了“ 新订购的2000列火 ”。以上只是选择了单个的文字,还没有跨标签进行选择,比如“  列火车因车体过宽,<strong>无法开进国内 ”这样的选择。也不会属性对其造成影响。假如anchorNode起点为“  司(SNCF)20日承认,</b>新订购的2000列火 ”这样的呢?anchorNode起点就为 B 标签里面的textNode,有部分属性就会产生变化。length:不变,都是textNode,nextSibling:变化了,B标签里面只有一个textnode,textnode的nextsibling就为null、previousSibling:和nextsibling 同理;textContent:不变;
  • anchorOffset:基于anchorNode也就是起点节点的偏移量,选中“  订购的2000列火车因车体过 ”这段话,起点节点为“ 新订购的2000列火车因车体过宽 “ 那么偏移量就为1;
  • baseNode:和anchorNode 属性一致。但是选择的起点不同的话则完全不一样。 假如选择 ” 订购的2000列火车因车体过 “ 这段话,anchorNode和baseNode的属性完全一致。假如选择起点为0,即anchorOffset为0的话属性就完全不一样了。比如”  新订购的2000列火车因车体过宽, “这段话,baseNode的起点就是这个textNode的previousSibling: B标签。其属性length、nextsibling,previoussibling都为B标签的文字节点属性 
  • baseOffset:和anchorOffset的一致,如果像”  新订购的2000列火车因车体过宽, “这段话的话,那么值就为previousSibling的textNode的length。
  • extentNode:selection选中文字的结束节点,假如选中的文字为“ 新订购的2000列火 ”,那么extentNode就为“ 新订购的2000列火车因车体过宽 ”,这个属性还有几个子属性,有用的几个和anchorNode和baseNode基本一致,length:这个节点的文字个数、nextSibling:这个文字节点的下一个同级节点,这里为 Strong标签、previousSibling:这个文字节点的前一个标签,这里是 B标签、textContent:这个选中的文字节点的全部文字,全部文字就是“ 新订购的2000列火车因车体过宽, ”即便只选择了“ 新订购的2000列火 ”。以上只是选择了单个的文字,还没有跨标签进行选择,比如“  列火车因车体过宽,<strong>无法开进国内 ”这样的选择的话,看最后选中的文字所处的地方,“  列火车因车体过宽,<strong>无法开进国内 ” 国内所处的标签是 Strong标签,那么extentNode就为Strong标签的 textNode,其length,nextSiblint,previousSibling,textContents都要做出相应的改变.
  • extentOffset:选中文字最后所处的标签的偏移量。“  列火车因车体过宽,<strong>无法开进国 ” 这个内字在Strong标签内所处的位置就是extentOffset的值。
  • focusNode:属性和定于与extentNode完全一致
  • focusOffset:属性和定义与extentOffset完全一致
  • getRangeAt:把选中的文字转化为range对象,可以进行操作。接受一个参数,一般填写为0,表示从selection对象的0开是进行转化;

以上的属性为chrome下console selection对象出来的与FF IE不一致,下面来说FF的selection对象属性,方法;

FF的selection 方法基本和chrome的一样,但是少了baseNode和extentNode以及extentOffset,baseOffset这4个属性,所以综上所述胃:起点节点用的属性为anchorNode,结束节点为focusNode的属性即可

IE下的的selection对象与上面又不相同为:

seletion对象属性和方法完全不同于W3C的selection之属性,方法;

                            RANGE对象

range对象也分为IE和W3C对象;range对象可以对选中的文字进行添加对象,删除,变粗,改变字体等适合用于网页富文本编辑等。在网上一搜一大片,我选几个目前能用到的属性来记录下。

W3C range:可以由selection对象创建也可以由document来创建。两者的区别为selection已经选好的range对象,通过selection.getRangeAt(0);来得到从selection 0开始的range对象;通过Document来创建就要稍微复杂一点,首先要确定range对象来自哪个元素,就拿上面的列子来讲;range对象来自P标签这个DOM对象;另外,range对象有4个基本属性:

  • startContainer:要选中的range对象开始的父节点,比如range对象是“法国国营铁路公司”   那么startContainer就是这个段文字所在标签B的文字节点。这个对象是可以被制定为文字节点或则一般节点。
  • startOffset:选中的range对象的起点,假如是文字节点,注释等,那么这个值就是这个range对象第一个字所在该文字节点的索引值;比如“国营铁路公司” 这个range对象第一个字是“国”,所在的text节点是“  法国国营铁路公司(SNCF)20日承认, ” 那么国字在这段文字的第2个。所以startOffset的值就为2。。万一我们选择的startContainer为一般节点,那么该值就为子节点的索引值;就拿上面列子来说,选择range对象为“ 无法开进国内许多火车站的站台,从而不得不花大笔资金改造站台。 ”,startContainer为P标签的话。那么startOffset就为“ 1 ”;
  • endOffset:选择规则和startOffset一致
  • endContainer:range结束时文字的父对象所在节点;比如” 台:“我们发现问题晚了点。<b>我们承认这一 “  那么endContainer就是B节点的文本节点;
  • commonAncestorContainer:endContainer和startContainer的共同父节点在这个Document最深的一个(最近的一个);比如“法国国营铁路公司“ 这种range对象所在End和startContainer的共同祖先都是文本节点。如果是跨标签的话,比如” 20日承认,</b>新订购的 “ startContainer是B标签的文本节点,endContainer是P标签。那么他们的共同祖先就是P标签;

一般选择:使用range.SelectNode(Dom)连同startContainer和endContainer一同选中;包含标签;range.SelectNodeContents(Dom);选中除了start,endContainer之外的内容,只是内容,不包含标签;

复杂选择:可以指定选择某段文字从哪开始从哪结束;有2个方法,为setStart,setEnd;方法分别接受2个参数,第一个参数为这个range对象的container,第2个参数为索引值;start和end2个方法的参数分别对应为setStart(startContainer,startOffset);setEnd(endContainer,endOffset);

以上就是range对象的基本属性和选择方式,分为selection选择和自己输入参数创建;下面就是实际操作range对象,让其实现富文本编辑;

  • insertNode:插入节点,创建一个节点,比如span标签,插入到这个range对象的开始处;用法:range.insertNode(span标签);
  • surroundContent:环绕节点,创建一个节点,比如span标签,把range对象添加进这个span标签。用处:一般用来设置其CSS样式等比如设置背景色;用法:range.surroundContents(span标签);(注:这个方法只能用于startContaienr和endContainer都是文本节点并且range没有跨标签。比如” 台:“我们发现问题晚了点。<b>我们承认这一 “  这种不行,要报错,解决方法是用extractContents方法提出来,添加进span,使用insetAdjacentHTML添加;

extractContents:提取并删除range对象,返回一个document.fragment对象;相当于我们的剪切功能;这方法和insertAdjacentHTML配合非常牛逼;例子:比如我们” 台:“我们发现问题晚了点。<b>我们承认这一 “  这种range对象的话有一部分的B标签在里面,那么使用这个方法的话,剪切后,B标签会自动补全开始和闭合标签,内容为剪切剩下的内容。比如剪切上面的range后,B标签就变成了<b>失误并为此承担责任。”</b> range中含有B标签部分的文字也会自动闭合成一个完整的B标签例如:<b>我们承认这一</b>; 

要使用insetAdjacentElement的话,必须知道调用insetAdjacentElement的节点为哪个。比如要把剪切出来的内容原原本本添加个背景色后还原,那么就必须知道确切的使用“insetAdjacentElement”的DOM节点。insetAdjacentElement可以添加在这个DOM节点的标签面前,内容开始前,内容结束后,标签结束后。分别为beforeBegin,beforeBegin,beforeEnd,afterEnd; 如何知道确切的调用这个方法的DOM节点呢?前面的selection对象的anchorNode和focusNode就派上用场了。我们分别得到这2个节点的父节点;总共有这么几种可能性:

1:假如起始节点的父节点不这个例子的根节点的话,那么说明range对象的anchroeNode是一个子节点而非文本节点,那么我们就把提取出来的range添加进span使用ahchorNode.insetAdjacentElement('afterEnd',span)来添到经过extractContents后自动闭合的起始节点的后面;

2:假如起始父节点为这个例子的根节点,但是结束父节点不是的话,那么就是FocusNode.insetAdjacentElement('beforeBegin',span)来添加到这个节点的前面;

3:假如起始父节点和结束父节点为相同的话,那么说明这个range的anchor和FocusNode都在子节点里面;使用surroundContents即可。

4:起始父节点为例子的根节点,结束父节点不是,那么就以结束父节点为起点,使用FocusNode.insetAdjacentElement('beforeBegin',span);

5:假如起始和结束父节点都是例子的话使用surroungContents即可。

但是有一点不同的是,在firefox下insetAdjacentElement不是一个有效的方法,firefox只支持insetAdjacentHTML。在chrome下HTML,TEXT,ELEMENT都支持。

目前在firefox下要使用怎么办呢?只支持insetAdjacentHTML的话我们就用span的innerHTML来拼接一个新的span就是了哇

如:FocusNode.insetAdjacentElement('beforeBegin',"<span style='background-color:red'>"+span.innerHTML+"</span>")   problem solved~~

                                                      IE下实现range给背景添加颜色等操作  

IE下的selection为document.selection;获取selection选中的range对象为document.selection.createRange();

由于IE的selection对象没有anchorNode等属性,所以添加背景色等操作就用不到insetAdjacentElement这样的函数,那么是怎么样进行操作的呢?

IE特有的execCommad来执行的,这个方法非常的强大,可以把range对象替换为其他的文本,input,img标签,还可以给range对象的文字进行样式设置;

获取range对象的方式和W3C一致,分别是通过selection 来获取,还有就是通过创建range对象;

selection创建:document.selection.createRange();

range对象创建:IE可以用不同标签来创建不同选择区域的range对象。比如用body创建range对象,那么range对象的选择区域就是整个页面了:获取整个body的range:document.body.createTextRange();目前IE range对象支持由body,input,button,textarea创建的range对象

简单的选择range对象:range.findText(”查找的文字“),返回一个bool值,true为找到值,false为没找到;例如上面的例子”  公司(SNCF) “  range.findText('公司(SNCF)'); 返回true,就可以使用execCommad操作对象了;注意:使用这个方法时候要注意range对象是由哪个标签创建的。比如Button创建的range对象要查找由textarea创建的range对象在textarea中的值,肯定是找不到的;

复杂的选择:IE range复杂的选择是通过moveStart,moveEnd来前后移动range选区;

这2个方法接受2个参数,第一个是移动的类型; 有4个类型:

character:按照字符进行移动,最小单位

word:按照单词进行移动;

sentence:按照句子进行移动;

textedit:直接移动到选区的结束位置,start传入这个参数无效,只有end方法传入才还效

第2个参数是数字,具体移动的个数,可以接受负值;start方法的数字是range开始起第几个开始计算;end方法的传入数字是这段range的结束位置起开始算,正数的话就是range的结束范围就是range本身的长度。负数的话那么就是range的长度减去负数值(绝对值);比如 一段完整的range文字,法国国营铁路公司(SNCF)20日承认,  我们要截取“铁路公司” 话看下面的例子:

这里用character来做例子;

range.moveStart('character',4);

range.moveEnd('character',-11);

那么range的范围就是创建这个range的元素的开始第4个到第8个之间的位置;

操作range对象

IE操作range对象全是通过execCommad来进行操作的

execCommad的参数有3个,

参数A,操作的类型比如设置range的css属性,剪切,复制,把range的文字转化成input、textarea标签等,

参数B,为bool值,在参数A为替换元素,添加链接的情况下才有用,目的为是否弹出框来确定这个操作,true为弹出,false为不弹出;

参数C,为参数A的具体属性,比如设置背景色的颜色,替换元素的ID属性,替换超链接的URL等;

参数A的部分参数为:

  • 2D-Position 允许通过拖曳移动绝对定位的对象。 
  • AbsolutePosition 设定元素的 position 属性为“absolute”(绝对)。 
  • BackColor 设置或获取当前选中区的背景颜色。 
  • BlockDirLTR 目前尚未支持。 
  • BlockDirRTL 目前尚未支持。 
  • Bold 切换当前选中区的粗体显示与否。 
  • BrowseMode 目前尚未支持。 
  • Copy 将当前选中区复制到剪贴板。 
  • CreateBookmark 创建一个书签锚或获取当前选中区或插入点的书签锚的名称。 
  • CreateLink 在当前选中区上插入超级链接,或显示一个对话框允许用户指定要为当前选中区插入的超级链接的 URL。 
  • Cut 将当前选中区复制到剪贴板并删除之。 
  • Delete 删除当前选中区。 
  • DirLTR 目前尚未支持。 
  • DirRTL 目前尚未支持。 
  • EditMode 目前尚未支持。 
  • FontName 设置或获取当前选中区的字体。 
  • FontSize 设置或获取当前选中区的字体大小。 
  • ForeColor 设置或获取当前选中区的前景(文本)颜色。 
  • FormatBlock 设置当前块格式化标签。 
  • Indent 增加选中文本的缩进。 
  • InlineDirLTR 目前尚未支持。 
  • InlineDirRTL 目前尚未支持。 
  • InsertButton 用按钮控件覆盖当前选中区。 
  • InsertFieldset 用方框覆盖当前选中区。 
  • InsertHorizontalRule 用水平线覆盖当前选中区。 
  • InsertIFrame 用内嵌框架覆盖当前选中区。 
  • InsertImage 用图像覆盖当前选中区。 
  • InsertInputButton 用按钮控件覆盖当前选中区。 
  • InsertInputCheckbox 用复选框控件覆盖当前选中区。 
  • InsertInputFileUpload 用文件上载控件覆盖当前选中区。 
  • InsertInputHidden 插入隐藏控件覆盖当前选中区。 
  • InsertInputImage 用图像控件覆盖当前选中区。 
  • InsertInputPassword 用密码控件覆盖当前选中区。 
  • InsertInputRadio 用单选钮控件覆盖当前选中区。 
  • InsertInputReset 用重置控件覆盖当前选中区。 
  • InsertInputSubmit 用提交控件覆盖当前选中区。 
  • InsertInputText 用文本控件覆盖当前选中区。 
  • InsertMarquee 用空字幕覆盖当前选中区。 
  • InsertOrderedList 切换当前选中区是编号列表还是常规格式化块。 
  • InsertParagraph 用换行覆盖当前选中区。 
  • InsertSelectDropdown 用下拉框控件覆盖当前选中区。 
  • InsertSelectListbox 用列表框控件覆盖当前选中区。 
  • InsertTextArea 用多行文本输入控件覆盖当前选中区。 
  • InsertUnorderedList 切换当前选中区是项目符号列表还是常规格式化块。 
  • Italic 切换当前选中区斜体显示与否。 
  • JustifyCenter 将当前选中区在所在格式化块置中。 
  • JustifyFull 目前尚未支持。 
  • JustifyLeft 将当前选中区所在格式化块左对齐。 
  • JustifyNone 目前尚未支持。 
  • JustifyRight 将当前选中区所在格式化块右对齐。 
  • LiveResize 迫使 MSHTML 编辑器在缩放或移动过程中持续更新元素外观,而不是只在移动或缩放完成后更新。 
  • MultipleSelection 允许当用户按住 Shift 或 Ctrl 键时一次选中多于一个站点可选元素。 
  • Open 目前尚未支持。 
  • Outdent 减少选中区所在格式化块的缩进。 
  • OverWrite 切换文本状态的插入和覆盖。 
  • Paste 用剪贴板内容覆盖当前选中区。 
  • PlayImage 目前尚未支持。 
  • Print 打开打印对话框以便用户可以打印当前页。 
  • Redo 目前尚未支持。 
  • Refresh 刷新当前文档。 
  • RemoveFormat 从当前选中区中删除格式化标签。 
  • RemoveParaFormat 目前尚未支持。 
  • SaveAs 将当前 Web 页面保存为文件。 
  • SelectAll 选中整个文档。 
  • SizeToControl 目前尚未支持。 
  • SizeToControlHeight 目前尚未支持。 
  • SizeToControlWidth 目前尚未支持。 
  • Stop 目前尚未支持。 
  • StopImage 目前尚未支持。 
  • StrikeThrough 目前尚未支持。 
  • Subscript 目前尚未支持。 
  • Superscript 目前尚未支持。 
  • UnBookmark 从当前选中区中删除全部书签。 
  • Underline 切换当前选中区的下划线显示与否。 
  • Undo 目前尚未支持。 
  • Unlink 从当前选中区中删除全部超级链接。 
  • Unselect 清除当前选中区的选中状态。

列如我们要设置背景色就为ragne.execCommad('BackColor','true','red');背景色为红色,其他css属性一直;

替换元素成TextBox并且把textbox的值设置为替换前的值:

var text=range.text;

range.execCommad('InsertInputText','false','tba');

document.getElementById('tba').value=text;

转自https://www.cnblogs.com/strangerqt/p/3745426.html


发布评论
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

关于window.getSelection知识解答
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。