【问题标题】:Click to remove the highlighted text单击以删除突出显示的文本
【发布时间】:2018-04-10 08:45:54
【问题描述】:

下面的代码允许我突出显示文本。有没有办法删除突出显示的文本(即不再突出显示的文本)

  1. 单击突出显示的文本,然后按“删除”按钮或
  2. 双击它?

我还希望从元素 highlights 中删除此突出显示的文本。

var lastSelection;
document.addEventListener("selectionchange", function() {
  lastSelection = window.getSelection();
});
var highlights = document.createElement("div");

function getRightClick(e) {
  var rightclick;
  if (!e) var e = window.event;
  if (e.which) rightclick = (e.which == 3);
  else if (e.button) rightclick = (e.button == 2);
  return rightclick; // true or false
}

function getSelectionCharacterOffsetsWithin(btnColor) {
  var selectedText = "null";
  if (typeof window.getSelection != "undefined") {
    var selection = window.getSelection();
    selectedText = selection.toString();
    var range = selection.getRangeAt(0);
    //Strip trailing punctation
    selectedText = selectedText.replace(/[\s.,!?:;'"-]+$/, "");
    //Leading space / quotes
    var offset = 0;
    var match = selectedText.match(/^[\s"']+/);
    if (match)
      offset = match[0].length;
    selectedText = selectedText.replace(/^[\s"']+/, "");
    if (selectedText === "") {
      alert("Error: you must select at least one character");
      tartOffset = 0, endOffset = 0, selectedText = "null";
    } else {
      var newInputid = parseInt(Math.random() * 10000);
      //This is code to keep word highlighted after selecting
      var newNode = document.createElement("span");
      newNode.classList.add('chosen');
      var previd = ("i" + newInputid);
      newNode.classList.add(previd);
      newNode.appendChild(range.extractContents());
      range.insertNode(newNode);
      var textSegment = $("." + previd);
      textSegment[0].style.backgroundColor = btnColor;
    }
  }
  return {
    text: selectedText,
    cid: previd
  };
}

$('.article').mousedown(function(event) {
  $('body').attr('mouse-top', event.clientY + window.pageYOffset);
  $('body').attr('mouse-left', event.clientX);

  if (!getRightClick(event)) {
    $('.entity_types').hide();
    document.getSelection().removeAllRanges();
  }
});

$('.article').mouseup(function(event) {
  if (lastSelection.toString().length > 1 && !getRightClick(event)) {
    $('.entity_types').css({
      display: 'block',
      position: 'absolute',
      top: event.clientY + 15,
      left: event.clientX + 10
    });

    $('.entity_types button').on('click', function(e) {
      e.preventDefault();
      var btnColor = $(this)[0].style.color;
      var selOffsets = getSelectionCharacterOffsetsWithin(btnColor);
      var selectedText = selOffsets.text;
      var selectedID = selOffsets.cid
      var txt = document.createTextNode(selectedText);
      highlights.appendChild(txt);
    });
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='entity_class' class="entity_types">
  <button class="btn" style="color:green">Class 1</button>
  <button class="btn" style="color:red">Class 2</button>
  <button class="btn" style="color:purple">Class 3</button>
</div>

<div class="article" style="overflow-x:auto;">
  What is missing from this statement, and likely to be asked by lawmakers, is why it took a newspaper to discover this breach of Facebook's systems. And, once Facebook knew, why it didn't notify the public and regulators immediately - instead of doing
  everything it could to block the story.
</div>

【问题讨论】:

  • 请在minimal reproducible example中包含此代码所作用的HTML。
  • 我也为你转换成sn-p,只保留对jQuery的引用并添加你的HTML。
  • 当您创建突出显示的跨度时,您不能绑定到它的点击事件吗?

标签: javascript jquery


【解决方案1】:

使用事件委托,这将在双击所有带有.chosen 类的span 时清除:

$('.article').on('dblclick', '.chosen', function() {
  (this).replaceWith(this.innerText);
});

例子:

var lastSelection;
document.addEventListener("selectionchange", function() {
  lastSelection = window.getSelection();
});
var highlights = document.getElementById("highlights");

function getRightClick(e) {
  var rightclick;
  if (!e) var e = window.event;
  if (e.which) rightclick = (e.which == 3);
  else if (e.button) rightclick = (e.button == 2);
  return rightclick; // true or false
}

function getSelectionCharacterOffsetsWithin(btnColor) {
  var selectedText = "null";
  if (typeof window.getSelection != "undefined") {
    var selection = window.getSelection();
    selectedText = selection.toString();
    var range = selection.getRangeAt(0);
    //Strip trailing punctation
    selectedText = selectedText.replace(/[\s.,!?:;'"-]+$/, "");
    //Leading space / quotes
    var offset = 0;
    var match = selectedText.match(/^[\s"']+/);
    if (match)
      offset = match[0].length;
    selectedText = selectedText.replace(/^[\s"']+/, "");
    if (selectedText === "") {
      alert("Error: you must select at least one character");
      tartOffset = 0, endOffset = 0, selectedText = "null";
    } else {
      var newInputid = parseInt(Math.random() * 10000);
      //This is code to keep word highlighted after selecting
      var newNode = document.createElement("span");
      newNode.classList.add('chosen');
      var previd = ("i" + newInputid);
      newNode.setAttribute('data-cid', previd);
      newNode.appendChild(range.extractContents());
      newNode.style.backgroundColor = btnColor;
      range.insertNode(newNode);
    }
  }
  return {
    text: selectedText,
    cid: previd
  };
}

$('.article').mousedown(function(event) {
  $('body').attr('mouse-top', event.clientY + window.pageYOffset);
  $('body').attr('mouse-left', event.clientX);

  if (!getRightClick(event)) {
    $('.entity_types').hide();
    document.getSelection().removeAllRanges();
  }
});

$('.article').mouseup(function(event) {
  if (lastSelection.toString().length > 1 && !getRightClick(event)) {
    $('.entity_types').css({
      display: 'block',
      position: 'absolute',
      top: event.clientY + 15,
      left: event.clientX + 10
    });
  }
});

$('.entity_types button').on('click', function(e) {
  e.preventDefault();
  var btnColor = $(this)[0].style.color;
  var selOffsets = getSelectionCharacterOffsetsWithin(btnColor);
  var selectedText = selOffsets.text;
  var selectedID = selOffsets.cid
  var txt = document.createTextNode(selectedText);
  var span = document.createElement('span');
  span.appendChild(txt);
  span.setAttribute('data-cid', selectedID);
  span.classList.add('highlighted');
  highlights.appendChild(span);
});

$('.article').on('dblclick', '.chosen', function() {
  var cid = this.getAttribute('data-cid');
  highlights.querySelector('[data-cid=' + cid + ']').remove();
  (this).replaceWith(this.innerText);
});
.highlighted:not(:last-child) {
  margin-right: 1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='entity_class' class="entity_types">
  <button class="btn" style="color:green">Class 1</button>
  <button class="btn" style="color:red">Class 2</button>
  <button class="btn" style="color:purple">Class 3</button>
</div>

<div class="article" style="overflow-x:auto;">
  What is missing from this statement, and likely to be asked by lawmakers, is why it took a newspaper to discover this breach of Facebook's systems. And, once Facebook knew, why it didn't notify the public and regulators immediately - instead of doing
  everything it could to block the story.
</div>

<br>

<div id="highlights"></div>

【讨论】:

  • 啊哈,这比我想象的要简单得多,非常感谢 Ori!这是否确保未突出显示的文本也从变量 highlights 中删除,之前它是作为 TextNode 添加的?
  • 不,不是。你用highlights 做什么?
  • 不要将 txt 添加到 div 中(如果有重复将更难找到),克隆 newNode 跨度并将其添加到 highlight,或者至少创建一个元素相同的 selectionID(应该是 data-* 而不是类)。现在您可以通过 selectionID 将其删除。
  • .data() 是一种将数据添加到 DOM 节点的 jquery 方式。由于您将 JS DOM 操作与 jquery 混合在一起,我不会那样做。使用.setAttribute() 添加data-cid 标签。我已经更新了演示来做到这一点。在添加和删除项目时可以看到高亮的内容。
  • 我还将$('.entity_types button').on('click', function(e) { 移到$('.article').mouseup(function(event) 事件处理程序之外,以防止向每个按钮多次添加点击处理程序。
猜你喜欢
  • 2011-08-31
  • 2020-11-12
  • 1970-01-01
  • 2011-09-04
  • 2017-11-18
  • 1970-01-01
  • 1970-01-01
  • 2012-06-23
  • 1970-01-01
相关资源
最近更新 更多