1

How can I highlight multiple HTML elements and remove them by pressing the Backspace key? WordPress block editor and Editor.js has this feature. Users can select/ Highlight multiple block and remove them by pressing the Backspace key. From this code below, If I highlight by selecting(mouse) not by clicking the .block-1, .block-2, .block-3 and press Backspace key then it should delete these elements.

[NOTE]

  1. Every block should have contenteditable attribute.
  2. Please, go to Editor.js first for demo what I exact want.
<div class="block-1" contenteditable="true"> 1st Block </div>
<div class="block-2" contenteditable="true"> 2nd Block </div>
<div class="block-3" contenteditable="true"> 3rd Block </div>
<div class="block-4" contenteditable="true"> 4th Block </div>

enter image description here

Tahazzot
  • 1,224
  • 6
  • 27
  • Did you try anything on your own to achieve this? – SMAKSS Sep 01 '20 at 09:44
  • I don't have any idea. How can I select multiple content editable div and delete them on btn press – Tahazzot Sep 01 '20 at 09:46
  • Somebody is on a downvote spree. But perhaps the question is just not clear. – html_programmer Sep 01 '20 at 10:15
  • @html_programmer Sorry for that, I don't know anything. But my question is now clear enough to get my answer. Please visit editor.js and then highlight some block by mouse and press backspace. It will delete these blocks. I need the same feature. – Tahazzot Sep 01 '20 at 10:28
  • I just updated my answer. You can select and deselect the `block` by highlighting the text inside it – AbbasEbadian Sep 01 '20 at 11:22
  • @Md.Tahazzot Can you check the answer, i updated it three times, now i think works as expected. – AbbasEbadian Sep 01 '20 at 12:09

2 Answers2

1

We need 2 listeners:

  • 1 - on mouseup, which catches selected text, and use TreeWalker to get all the highlighted elements and toggle selected class on .blocks.
  • 2 - on keyup, which will catch backspace

Edit:

Used This and improved the answer .

$(document).on({
  'keyup': function(e) {
    if (e.which == 8)
      $('div.block.selected').remove();
  },
  'mouseup': getSelectedElementTags
});


function rangeIntersectsNode(range, node) {
  var nodeRange;
  if (range.intersectsNode) {
    return range.intersectsNode(node);
  } else {
    nodeRange = node.ownerDocument.createRange();
    try {
      nodeRange.selectNode(node);
    } catch (e) {
      nodeRange.selectNodeContents(node);
    }

    return range.compareBoundaryPoints(Range.END_TO_START, nodeRange) == -1 &&
      range.compareBoundaryPoints(Range.START_TO_END, nodeRange) == 1;
  }
}

function getSelectedElementTags() {
  var win = window;
  var range, sel, elmlist, treeWalker, containerElement;
  sel = win.getSelection();
  if (sel.toString().length == 0) return
  if (sel.rangeCount > 0) {
    range = sel.getRangeAt(0);
  }

  if (range) {
    containerElement = range.commonAncestorContainer;
    if (containerElement.nodeType != 1) {
      containerElement = containerElement.parentNode;
    }

    treeWalker = win.document.createTreeWalker(
      containerElement,
      NodeFilter.SHOW_ELEMENT,
      function(node) {
        return rangeIntersectsNode(range, node) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
      },
      false
    );

    elmlist = [treeWalker.currentNode];
    while (treeWalker.nextNode()) {
      elmlist.push(treeWalker.currentNode);
    }
    elmlist.forEach(function(e) {
      if ($(e).hasClass('block')) {
        $(e).toggleClass('selected');
      }
    });
    sel.empty()
  }
}
div.block.selected {
  background-color: #ddf;
}

div.block {
  margin: 24px;
  border-bottom: 1px solid #ddd;
  font-size: 13px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container" contenteditable="true">
  <div class="block block-1" contenteditable="true"> 1st Block</div>
  <div class="block block-2" contenteditable="true"> 2nd Block </div>
  <div class="block block-3" contenteditable="true"> 3rd Block</div>
  <div class="block block-4"> 4th Block </div>
</div>
AbbasEbadian
  • 653
  • 5
  • 15
  • Thanks. But I need all the block elements with contenteditable attr. Same as Editor.js/ WP block editor. (You get the idea) – Tahazzot Sep 01 '20 at 14:09
-1

The CSS and the contenteditable attribute are not necessary. Here is the code

var targeted;

document.getElementById('container').addEventListener('click', function(event) {
    console.log(event.target); // You can see here the targeted element
    if(event.target.id !== 'container') {
        targeted = event.target;
    } else {
        targeted = undefined;
    };
});

document.addEventListener('keydown', function(event) {
    if(event.keyCode === 8 && targeted) {
        targeted.parentNode.removeChild(targeted);
    };
});
#container {
    padding: 20px;
    background-color: black;
}
#container div {
    margin-bottom: 5px;
    height: 50px;
    width: 200px;
    background-color: white;
}
<div id="container">
    <div contenteditable="true">1</div>
    <div contenteditable="true">2</div>
    <div contenteditable="true">3</div>
    <div contenteditable="true">4</div>
    <div contenteditable="true">5</div>
</div>
smunteanu
  • 422
  • 3
  • 9