将.getSelection()调用中存储的选择存储到数组中后,如何选择该选择

时间:2019-04-24 13:16:18

标签: range selection highlight getselection

我正在尝试创建一个小脚本,以便可以在任何可用于学习的页面(数字版本的带有黄色标记的书中突出显示文本)上轻松标记(突出显示)文本。

我真的不太了解.getSelection()函数,以及如何处理从中获得的Selection和Range,所以我希望这里有人可以帮助我。

以下是一些图片,希望能解释我要完成的工作。

First explanation image

Second explanation image

Third explanation image

Fourth explanation image

这是我的脚本代码。我是JS编码的新手,我主要是为了练习和娱乐,所以很抱歉,如果某些代码看起来不好:

https://codepen.io/MathiasWP/pen/axREWb

// The pop-up box is created from scratch here in JS
const mainText = `
<p>Export</p>
<h2>Marked elements:</h2>
 <span class="marked"></span>`;

const popup = document.createElement("div");

setTimeout(() => {
  document.body.appendChild(popup);

  // Pop-up box gets some preset text
  popup.innerHTML = mainText;
}, 200);


// Styling of the pop-up box
popup.style.visibility = "hidden";
popup.style.width = "300px";
popup.style.position = "fixed";
popup.style.zIndex = "100";
popup.style.bottom = "0";
popup.style.right = "0";
popup.style.marginRight = "10px";
popup.style.color = "white";
popup.style.backgroundColor = "#282c34";
popup.style.padding = "20px";
popup.style.borderRadius = "15px 15px 0px 0px";
popup.style.maxHeight = "400px";
popup.style.overflowY = "scroll";
popup.style.fontFamily = '"Trebuchet MS", Helvetica, sans-serif';

// The selected text gets set to the variable
let selection = window.getSelection();

// Array where all selected text will be stored
const selected = [];

// Variable that stores all of the text on the entire page as a string
setTimeout(() => {
  const pageText = document.body.innerText.toString();
}, 200);

mouseUp = e => {
  // If nothing is selected, return
  if (selection.isCollapsed) return;
  //Kind of a bug fix, where if the marked text is 100% equal the last selected then it also will return (this fixed a small bug where if you marked a text and clicked on the screen it would be stored again)
  else if (selection.toString() === selected.slice(-1)[0]) {
    return;
  }
  // Here's where all the fun begins
  else {
    // If selected text is just whitespace then nothing happens (just for practical use)
    if (!selection.toString().replace(/\s/g, "").length) return;
    else {
      if (!e) e = window.event;
      // If command/ctrl button is held when text is marked, the function will run the main stuff
      if (e.metaKey) {
        // Just an awkard way to make the popup show up when text has been marked, could find a better way to to this but i'm lazy right now
        popup.style.visibility = "visible";

        // The selected text gets pushed to the selected-text-array
        selected.push([
          selection,
          selection.toString(),
          selection.anchorOffset,
          selection.focusOffset,
          selection.getRangeAt(0)
        ]);

        // Design Mode gets turned on, found this was the easiest way to highlight the selected text on the page
        document.designMode = "on";

        // Where the selected text gets the background-color changed
        // The color of selected text in Google Chrome is #bad6fb. That one can also be used (looks kinda cool).
        document.execCommand("backColor", false, "yellow");

        // Design mode gets turned off
        document.designMode = "off";

        console.log(selection);
        console.log(selection.getRangeAt(0));

        console.log(selected);

        // Runs the function that writes everything in the pop-up box
        updateBox();

      }
    }
  }
};

// Function that removes the chosen element in the list. Could've made everything prettier and easier with for example jQuery, but decided to make everything pure vanilla JS
removeMark = element => {

  let thisElement = [selected[element.id.replace("marked-id-", "")][0], selected[element.id.replace("marked-id-", "")][4]];

  console.log(thisElement);


node = thisElement[1].startContainer;

if (document.body.createTextRange) {
    const range = document.body.createTextRange();
    range.moveToElementText(node);
    range.select();
} else if (window.getSelection) {
    const selection = thisElement[0];
    const range = thisElement[1];
    range.selectNodeContents(node);
    selection.removeAllRanges();
        selection.addRange(range);
} else {
    console.warn("Could not select text in body: Unsupported browser.");
}

  // Desin mode ON
  document.designMode = "on";

  // Removes selected color

  //document.execCommand("backColor", false, "pink");

  // Design mode OFF
  document.designMode = "off";

  // Removes the element from the selected-text array
  selected.splice(thisElement, 1);

  // Runs function that writes what should be in the box (doing this everytime to update the id's of the other elements in the box when something gets removed)
  updateBox();

  // Hides the pop-up box if nothing selected (used to remove the pop-up box if everything in it is removed by the user)
  if (selected.length === 0) {
    popup.style.visibility = "hidden";
  }
};


updateBox = () => {
   // Awkward way to make all the selected text displayed in the pop-up box. First everything gets removed and set to start...
   popup.innerHTML = mainText;

  // ... and then every element gets inserted adjacently after each other
  selected.forEach(el =>
  document
    .querySelector(".marked")
    .insertAdjacentHTML(
      "beforeend",
      `<span><br><b>-</b> ${
        el[1]
      } <p style="color:red;cursor:pointer" id="marked-id-${selected.indexOf(el)}" onclick="removeMark(this); return false;">(remove)</p><br></span>`
    )
);
}

// Part of the script that actually makes everything happen after mouse is no longer held down
window.addEventListener("mouseup", mouseUp);

我还遇到了其他一些问题。例如,当我尝试选择上一个文本时(如图4所示),那么有时会选中整个段落。我遇到的另一个错误是当我在控制台日志“ thisElement”中登录时,baseNode,anchorNode,endContainer等变量被更改。我真的不知道为什么更改它,因为它只是存储在“ selected”数组中,但是如果有人知道,请解释为什么这样做:)

0 个答案:

没有答案