Highliting text in html page having only xPath, anchorOffset and focusOffset

我的未来我决定 提交于 2019-12-07 22:24:08

问题


I'm trying to hightlight some part of a text in a html page having only the xPath (or css path) of the selected area, an anchorOffset and a focusOffset.

I know how to manage this using the selection() method from user input, but i'm having serious difficulties trying to reproduce the same mechanism in an automathic way without the selection but only with these infos

Example: (imagine I have many others like this)

Xpath : heyThere[1]
anchorOffset  : 3
focusOffset : 45

My goal is something like this

(see pic) http://oi57.tinypic.com/68aebo.jpg

can anybody give me an hint for this task?

Thanks a lot!


回答1:


I don't see how a relative path like heyThere[1] would select anything in an HTML document as the root element name is html and not heyThere. As for styling a certain part, assuming you have a path leading to a text node and the offsets are inside that text node, you can create a range using the W3C DOM Level 2 Rang API, create a span with a certain CSS class as a wrapper and that way the text can be highlighted. Note that support for that DOM API is not available in older IE versions, I think only Edge on Windows 10 supports document.evaluate with XPath and I am not sure about the range support.

function highlight(textNode, start, end) {
  var range = document.createRange();
  range.setStart(textNode, start);
  range.setEnd(textNode, end);
  var span = textNode.ownerDocument.createElement('span');
  span.className = 'highlight';
  range.surroundContents(span);
}

window.onload = function() {
  var testData = [
    {
      path: 'html/body/section/h1/text()',
      start: 3,
      end: 5
    },
    {
      path: 'html/body/section/div/ul/li[2]/text()',
      start: 12,
      end: 19
    },
    {
      path: '//p',
      start: 1,
      end: 1
    }
  ];
  for (var i = 0; i < testData.length; i++) {
    var node = document.evaluate(testData[i].path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
    if (node !== null) {
      highlight(node, testData[i].start, testData[i].end);
    }
    else {
      console.log('No node found for path ' + testData[i].path);
    }
  }
};
.highlight {
  color: brown;
  font-weight: bold;
}
<section>
  <h1>Example</h1>
  <div>
    <ul>
      <li>This is list item 1.</li>
      <li>This is list item 2.</li>
    </ul>
  </div>
</section>
  

I looked up the IE support, the range API is supported since IE 9 so only the XPath based access does not work, an example for IE using CSS based node selection is

function highlight(textNode, start, end) {
  var range = document.createRange();
  range.setStart(textNode, start);
  range.setEnd(textNode, end);
  var span = textNode.ownerDocument.createElement('span');
  span.className = 'highlight';
  range.surroundContents(span);
}

window.onload = function() {
  var testData = [
    {
      css: 'section > h1',
      start: 3,
      end: 5
    },
    {
      css: 'section > div > ul li:nth-child(2)',
      start: 12,
      end: 19
    },
  ];
  for (var i = 0; i < testData.length; i++) {
    var node = document.body.querySelector(testData[i].css);
    if (node !== null) {
      highlight(node.firstChild, testData[i].start, testData[i].end);
    }
    else {
      console.log('No node found for CSS selector ' + testData[i].css);
    }
  }
};
.highlight {
  color: brown;
  font-weight: bold;
}
<section>
  <h1>Example</h1>
  <div>
    <ul>
      <li>This is list item 1.</li>
      <li>This is list item 2.</li>
    </ul>
  </div>
</section>


来源:https://stackoverflow.com/questions/31996357/highliting-text-in-html-page-having-only-xpath-anchoroffset-and-focusoffset

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!