• 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 操作,这是一个很复杂的操作

  • 相关阅读:
    51nod1376 最长递增子序列的数量
    51nod1201 整数划分
    51nod1202 子序列个数
    51nod 博弈论水题
    51nod1052 最大M子段和
    51nod1678 lyk与gcd
    51nod1262 扔球
    BZOJ2763, 最短路
    吃西瓜 最大子矩阵 三维的。 rqnoj93
    noip2015 信息传递 强连通块
  • 原文地址:https://www.cnblogs.com/ssaylo/p/13278399.html
Copyright © 2020-2023  润新知