JS 点击按钮标记鼠标选中文本&&取消标记

目录:

 

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      div {
        padding: 30px;
      }

      .highlight {
        background-color: yellow;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <section>
        <h1>Heading 1</h1>
        Text without tag
        <p id="p1">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Quae esse
          tempora architecto, debitis fugit
          <span style="color: red;">Span Text</span> amet mollitia quidem minima
          numquam suscipit labore quod magnam temporibus odit sint totam itaque
          quo maxime.
        </p>
        <p id="p2">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptas
          cupiditate ratione ullam veniam ab corporis, tempore impedit repellat
          mollitia incidunt error fuga voluptates omnis, qui enim sapiente ut
          culpa ipsum?
        </p>
        <p id="p3">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Distinctio,
          laboriosam inventore nemo id architecto nostrum ipsum est culpa hic
          recusandae qui ad consequuntur! Deleniti dolorem quae reprehenderit
          quasi! Iusto, dolores!
        </p>
      </section>
      <section>
        <h1>Heading 2</h1>
        Text without tag
        <p id="p1">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Quae esse
          tempora architecto, debitis fugit
          <span style="color: red;">Span Text</span> amet mollitia quidem minima
          numquam suscipit labore quod magnam temporibus odit sint totam itaque
          quo maxime.
        </p>
        <p id="p2">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptas
          cupiditate ratione ullam veniam ab corporis, tempore impedit repellat
          mollitia incidunt error fuga voluptates omnis, qui enim sapiente ut
          culpa ipsum?
        </p>
        <p id="p3">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Distinctio,
          laboriosam inventore nemo id architecto nostrum ipsum est culpa hic
          recusandae qui ad consequuntur! Deleniti dolorem quae reprehenderit
          quasi! Iusto, dolores!
        </p>
      </section>
      <section>
        <h1>Heading 3</h1>
        <p id="p4">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Quae esse
          tempora architecto, debitis fugit
          <span style="color: red;">Span Text</span> amet mollitia quidem minima
          numquam suscipit labore quod magnam temporibus odit sint totam itaque
          quo maxime.
        </p>
        <p id="p5">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptas
          cupiditate ratione ullam veniam ab corporis, tempore impedit repellat
          mollitia incidunt error fuga voluptates omnis, qui enim sapiente ut
          culpa ipsum?
        </p>
        <p id="p6">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Distinctio,
          laboriosam inventore nemo id architecto nostrum ipsum est culpa hic
          recusandae qui ad consequuntur! Deleniti dolorem quae reprehenderit
          quasi! Iusto, dolores!
        </p>
      </section>
    </div>

    <button id="highlightButton">Highlight</button>

    <script src="src/index.js"></script>
  </body>
</html>

 index.js

console.clear();

document.getElementById("highlightButton").addEventListener("click", () => {
  document.getElementById("highlightButton").disabled = true;
  highlight();
});

function highlight() {
  const sel = window.getSelection();
  const range = sel.getRangeAt(0);
  const {
    commonAncestorContainer,
    startContainer,
    endContainer,
    startOffset,
    endOffset
  } = range;
  const nodes = [];

  console.group("range");

  console.log("rage", range);
  console.log("commonAncestorContainer", commonAncestorContainer);
  console.log("startContainer", startContainer);
  console.log("endContainer", endContainer);
  console.log("startOffset", startOffset);
  console.log("endOffset", endOffset);
  console.log("startContainer.parentNode", startContainer.parentNode);
  console.groupEnd();

  if (startContainer === endContainer) {
    const span = document.createElement("span");
    span.className = "highlight";
    range.surroundContents(span);
    nodes.push(startContainer);
    console.log(nodes);
    return;
  }

  // get all posibles selected nodes
  function getNodes(childList) {
    console.group("***** getNode: ", childList);
    childList.forEach((node) => {
      console.log("node:", node, "nodoType", node.nodeType);

      const nodeSel = sel.containsNode(node, true);
      console.log("nodeSel", nodeSel);

      // if is not selected
      if (!nodeSel) return;

      const tempStr = node.nodeValue;
      console.log("nodeValue:", tempStr);

      if (node.nodeType === 3 && tempStr.replace(/^\s+|\s+$/gm, "") !== "") {
        console.log("nodo agregado");
        nodes.push(node);
      }

      if (node.nodeType === 1) {
        if (node.childNodes) getNodes(node.childNodes);
      }
    });
    console.groupEnd();
  }

  getNodes(commonAncestorContainer.childNodes);

  console.log(nodes);

  nodes.forEach((node, index, listObj) => {
    const { nodeValue } = node;
    let text, prevText, nextText;

    if (index === 0) {
      prevText = nodeValue.substring(0, startOffset);
      text = nodeValue.substring(startOffset);
    } else if (index === listObj.length - 1) {
      text = nodeValue.substring(0, endOffset);
      nextText = nodeValue.substring(endOffset);
    } else {
      text = nodeValue;
    }

    const span = document.createElement("span");
    span.className = "highlight";
    span.append(document.createTextNode(text));
    const { parentNode } = node;

    parentNode.replaceChild(span, node);

    if (prevText) {
      const prevDOM = document.createTextNode(prevText);
      parentNode.insertBefore(prevDOM, span);
    }

    if (nextText) {
      const nextDOM = document.createTextNode(nextText);
      parentNode.insertBefore(nextDOM, span.nextSibling);
    }
  });

  sel.removeRange(range);
}

效果图:

取消标记,改个class就好了~~

找了半天终于找到可用的~

https://stackoverflow.com/questions/29894781/javascript-selected-text-highlighting-prob/66878952#66878952

https://codesandbox.io/s/api-selection-multiple-with-nodes-forked-tzvkd

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值