How can I highlight a word/term quicker and smarter?

后端 未结 6 815
误落风尘
误落风尘 2021-02-05 06:27

I have some text:

Hello world, Attack on Titan season two!

Currently, if a user wants to highlight a word/ter

6条回答
  •  轮回少年
    2021-02-05 07:08

    This text is a text node, and text nodes simply don't fire most events. But they can fire DOM mutation events, for example DOMCharacterDataModified, which is used to detect change to a text node's text:

    var textNode = document.getElementsByClassName("drag")[0].firstChild;
    
    textNode.addEventListener("DOMCharacterDataModified", function(e) {
        console.log("Text changed from '" + e.prevValue + "' to '" + evt.newValue +"'");
    }, false);
    

    However, the text in

    Hello world, Attack on Titan season two!

    is a single text node and you need every word to be a separate node.

    The only solution I see is to put every word in a span tag. You can't do this with pure text.

    Edit

    Here's an example how to do this with span tags (I'm using jQuery here just to reduce the code amount, it's not necessary):

    $(function() {
        $('.drag').on('click', 'span', function() {
            var range;
            if (document.selection) {
                range = document.body.createTextRange();
                range.moveToElementText($(this)[0]);
                range.select();
            } 
            else if (window.getSelection) {
                range = document.createRange();
                range.selectNode($(this)[0]);
                window.getSelection().addRange(range);
            }
        });  
    });
    

    Here's an example on JS Bin

    Update

    I edited the code snippet so the selection behaves like you asked (currently it's only works for selections from left to right, not reverse selections):

    $(function(){
    
      var range = document.createRange();
      var selectionMode = false;
    
      $(document).on('mouseup', function() {
        selectionMode = false;
      })
      .on('mousedown', '.drag', function(e) {
        selectionMode = true;
      })
      .on('dragstart', '.drag span', function(e) {
        return false;
      });
    
      $('.drag').on('mousedown', 'span', function() {
        range.setStartBefore($(this)[0]);
        range.setEndAfter($(this)[0]);
        window.getSelection().addRange(range);
      })
      .on('mousemove', 'span', function() {
        if (!selectionMode) {
          return;
        }
        range.setEndAfter($(this)[0]);
        window.getSelection().addRange(range);
      })
      .on('mouseup', 'span', function() {
        setTimeout(function(){
          window.getSelection().addRange(range);
        }, 1);
      });  
    
    });
    

    You can read more about HTML Range API here: https://developer.mozilla.org/en-US/docs/Web/API/Range

提交回复
热议问题