以这段文字为例子。。
<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
喜欢这篇文章?欢迎打赏~~