zoukankan      html  css  js  c++  java
  • getSelection、range 对象属性,方法理解,解释

    网上转了一圈发现没有selection方面的解释,自己捣鼓下

    以这段文字为例子。。

    <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;

  • 相关阅读:
    2.vue插件总结——总有你能用上的插件
    1.前端数据可视化插件:Highcharts、Echarts和D3(区别)
    git学习地址
    node vue 微信公众号(四)配置环境 本地测试
    解决element 分页组件,搜索过后current-page 绑定的数据变了,但是页面当前页码并没有变的问题
    导入excel并进行数据提取
    后端返回字符串中带换行符,前端需转换
    正则表达式tab表示
    FormData
    interval
  • 原文地址:https://www.cnblogs.com/strangerqt/p/3745426.html
Copyright © 2011-2022 走看看