Detecting Word under the cursor

2019-06-14 20:17发布

问题:

How best to detect the word under the cursor using JavaScript?

I know that this question has been asked before, but the solutions that I have seen do not work in all scenarios.

I have isolated some locations where the code does not work and placed it in a JSFiddle container (http://jsfiddle.net/ohaf4ytL/). Follow along in console, and you can see that "Блгcви2 душE моS" only lists "Блгcви2" and not "душE" and "моS" when hovered over.

The current code in use is taken from How to get a word under cursor using JavaScript? answer by Eyal. It is not an accepted answer, but there's not a large choice of options. Adding spans is a hack and also does not handle cases like Abc. The range.expand('word') feature cuts off when there are characters such as ) inside a word (and my text has this), but I think that's not the only issue.

function getWordAtPoint(elem, x, y) {
  if(elem.nodeType == elem.TEXT_NODE) {
    var range = elem.ownerDocument.createRange();
    range.selectNodeContents(elem);
    var currentPos = 0;
    var endPos = range.endOffset;
    while(currentPos+1 < endPos) {
      range.setStart(elem, currentPos);
      range.setEnd(elem, currentPos+1);
      if(range.getBoundingClientRect().left <= x && range.getBoundingClientRect().right  >= x &&
         range.getBoundingClientRect().top  <= y && range.getBoundingClientRect().bottom >= y) {
        range.expand("word");
        var ret = range.toString();
        range.detach();
        return(ret);
      }
      currentPos += 1;
    }
  } else {
    for(var i = 0; i < elem.childNodes.length; i++) {
      var range = elem.childNodes[i].ownerDocument.createRange();
      range.selectNodeContents(elem.childNodes[i]);
      if(range.getBoundingClientRect().left <= x && range.getBoundingClientRect().right  >= x &&
         range.getBoundingClientRect().top  <= y && range.getBoundingClientRect().bottom >= y) {
        range.detach();
        return(getWordAtPoint(elem.childNodes[i], x, y));
      } else {
        range.detach();
      }
    }
  }
  return(null);
}    

回答1:

A way of accomplishing what you want would be to split the sentence into html elements and then listening to a hover event. For example, using jQuery:

HTML:

<div id="text"> Блгcви2 душE Блгcви2 This is a test</div>

JavaScript:

var div = $("#text");
div.html(div.text().replace(/(\S+)/g, "<span>$1</span>"));

$("#text span").hover(function(event){
    console.log($(this).text());
});

I looked for anything that's not a space with the regex \S and the HTML is now updated to:

<div id="text"> 
  <span>Блгcви2</span>
  <span>душE</span>
  <span>Блгcви2</span>
  <span>This</span>
  <span>is</span>
  <span>a</span>
  <span>test</span>
</div>

When you hover over a word, the word will printed out in the console of your browser.