zoukankan      html  css  js  c++  java
  • DOM Range Api

    Range Api 1

    (必要的 api)

    • var range = new Range();
    • range.setStart(element, 9);
    • range.setEnd(element, 4);
    • var range = document.getSelection().getRangeAt(0);

    也就是说,range 有两种创建方式

    第一种,new Range()然后 setStart、setEnd

    第二种,getSelection 然后 getRangeAt

    Range Api 2

    (可选的,方便 DOM 操作的 api)

    针对单个node 的操作

    • range.setStartBefore
    • range.setEndBefore
    • range.setStartAfter
    • range.setEndAfter
    • range.selectNode
    • range.selectNodeContents

    Range Api 3

    (拿到 range 了以后可以做的事情)

    • var fragment = range.extractContents()

      fragment 其实是一种文档的片段,当我们 append 一个 fragment 到 DOM 树的时候,append 上去的玩意儿其实是 fragment 里面的所有子元素,而 fragment 并没有挂载到 DOM 树中。

    • range.insertNode(document.createTextNode("aaa"))

      我们使用 document.insertBefore 和 document.appendChild 的时候,只能在两个元素之间或者前后插入元素,而无法精确操作。(元素跟元素之间)

      当使用 range.insertNode的时候,我们可以精确到两个 DOM 之间的具体的 text 中的位置,在该位置插入一个 Node。(文本跟文本之间)

    上面这两个 api 的配合使用,有奇效。

    实战

    eg1

    <div id="a">
      <span>1</span>
      <p>2</p>
      <a>3</a>
      <div>4</div>
    </div>
    <script>
    	let element = document.getElementById("a");
      function reverseChildren() {
        let range = new Range();
        range.selectNodeContents(element);
        let fragment = range.extractContents();
        var l = fragment.childNodes.length;
        while(l-- > 0) {
          fragment.appendChild(fragment.childNodes[l]);
        }
        element.appendChild(fragment);
      }
      reverseChildren();
    </script>
    

    eg2

    <div id="a">
      123456789
    </div>
    <script>
    	let element = document.getElementById('a');
      let range = new Range();
      range.setStart(element, 0);
      range.setEnd(element, 1);
      console.log(range);
      range.extractContent();
    </script>
    

    eg3

    <div id="a">
      123456789
    </div>
    <script>
      let element = document.getElementById("a").childNodes[0];
      let range = new Range();
      range.setStart(element, 0);
      range.setEnd(element, 4);
      console.log(range);
      range.extractContents();
    </script>
    

    eg4

    <div id="a">
      12345<span style="background-color: aqua;">456789</span>01111111111
    </div>
    <script>
      let range = new Range();
      range.setStart(document.getElementById("a").childNodes[1].childNodes[0], 0);
      range.setEnd(document.getElementById("a").childNodes[2], 3);
      // range.extractContents();
    </script>
    

    做富文本编辑器的时候,rangeApi 也很有用,省得光标去乱跳。

    不过一般来说,我们也用不到富文本编辑器。

    据说,做富文本编辑器,可以到阿里的 p7 的水准了。

    不仅仅是一个 DOM 操作,这是一个很复杂的操作

  • 相关阅读:
    Lucene 全文检索
    Redis 集群
    Redis 初步接触
    Mybatis
    FastJson 介绍
    JAVA微信企业付款到零钱(十分钟搞定),附完整DEMO下载
    持续集成与Devops关系
    GIT命令行统计代码提交行数
    一种简单的REST API接口加密实现,只允许自己的产品调用后台,防止接口被刷
    Beyond Compare 4.X 破解方法(亲测有效)
  • 原文地址:https://www.cnblogs.com/ssaylo/p/13278399.html
Copyright © 2011-2022 走看看