Applying DIV/Span tag to a word by specific co-ordinates

早过忘川 提交于 2019-12-04 19:12:01

The only method I can think of involves wrapping every word in a span element, and then using document.elementFromPoint(x,y) to get the span element at the given location. Something like this:

function highlightWordAtXY(x, y) {
    // Get the element containing the text
    var par = document.elementFromPoint(x, y),
        // textContent or innerText ?
        t = "textContent" in par ? "textContent" : "innerText",
        // Get the text of the element. No pun intended on the par[t].
        text = par[t],
        result;

    // Wrap a span around every word
    par.innerHTML = text.replace(/\b(\w+)\b/g, "<span>$1</span>");

    // Get the elementFromPoint again, should be a span this time
    result = document.elementFromPoint(x, y);

    // Check that we actually clicked on a word
    if (result == par)
        return false;

    // Wrap HTML text around the text at x, y
    result[t] = '<span class="highlight">' + result[t] + '</span>';

    // Restore the content with the wrapped text
    par.innerHTML = par[t];
}

Example at http://jsfiddle.net/BSHYp/1/show/light/ - click a word and watch it highlight.

Some important caveats here:

  • Each block of text must be wrapped in an element (such as <p> or <div>). You should be wrapping paragraphs in <p> tags anyway,
  • The element at the given location (x, y) must only have text in it, no child HTML elements. Text nodes with sibling HTML elements will have them removed (e.g. Clicking "Some" or "here" in Some <b>text</b> here will remove the <b> tags). Dividing them into separate <span> elements would be the only solution without building a much more complex routine,
  • IE will throw an "Unknown runtime error" if you try and add a block level element to a <p> tag,
  • On very, very, very large blocks of text you might run into performance issues. Break them up where applicable.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!