admin管理员组

文章数量:1024054

Given the HTML as a string, the Xpath and offsets. I need to highlight the word.

In the below case I need to highlight Child 1

HTML text:

<html>
 <body>
       <h2>Children</h2>Joe has three kids:<br/>
       <ul>
        <li>
        <a href="#">Child 1 name</a>
        </li>
        <li>kid2</li>
        <li>kid3</li>
       </ul>
 </body>
</html>

XPATH as : /html/body/ul/li[1]/a[1]

Offsets: 0,7

Render - I am using react in my app. The below is what I have done so far.

public render(){
  let htmlText = //The string above
  let doc = new DOMParser().parseFromString(htmlRender,'text/html');
  let ele = doc.evaluate("/html/body/ul/li[1]/a[1]", doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); //This gives the node itself
  let spanNode = document.createElement("span");
  spanNode.className = "highlight";

  spanNode.appendChild(ele);
  // Wrapping the above node in a span class will add the highlights to that div
  //At this point I don't know how to append this span to the HTML String
  return(
    <h5> Display html data </h5>
    <div dangerouslySetInnerHTML={{__html: htmlText}} />
   )

I want to avoid using jquery. Want to do in Javascript(React too) if possible!

Edit:

So if you notice the Render function it is using dangerouslySetHTML. My problem is I am not able manipulate that string which is rendered.

Given the HTML as a string, the Xpath and offsets. I need to highlight the word.

In the below case I need to highlight Child 1

HTML text:

<html>
 <body>
       <h2>Children</h2>Joe has three kids:<br/>
       <ul>
        <li>
        <a href="#">Child 1 name</a>
        </li>
        <li>kid2</li>
        <li>kid3</li>
       </ul>
 </body>
</html>

XPATH as : /html/body/ul/li[1]/a[1]

Offsets: 0,7

Render - I am using react in my app. The below is what I have done so far.

public render(){
  let htmlText = //The string above
  let doc = new DOMParser().parseFromString(htmlRender,'text/html');
  let ele = doc.evaluate("/html/body/ul/li[1]/a[1]", doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); //This gives the node itself
  let spanNode = document.createElement("span");
  spanNode.className = "highlight";

  spanNode.appendChild(ele);
  // Wrapping the above node in a span class will add the highlights to that div
  //At this point I don't know how to append this span to the HTML String
  return(
    <h5> Display html data </h5>
    <div dangerouslySetInnerHTML={{__html: htmlText}} />
   )

I want to avoid using jquery. Want to do in Javascript(React too) if possible!

Edit:

So if you notice the Render function it is using dangerouslySetHTML. My problem is I am not able manipulate that string which is rendered.

Share Improve this question edited Mar 20, 2017 at 4:18 suprita shankar asked Mar 18, 2017 at 3:01 suprita shankarsuprita shankar 1,5892 gold badges19 silver badges50 bronze badges 2
  • It may be just me, but it's not very clear what exactly you need to acplish? Do you need to simply modify the value of htmlText before you put it in dangerouslySetInnerHtml? – hazardous Commented Mar 21, 2017 at 8:15
  • Is this your actual code snippet or just an example? Lot of stuff is puzzling here, there is the public before render, then you are trying to nest html inside a div. Could you please share a more plete code? git repo would be preferable. – hazardous Commented Mar 21, 2017 at 8:17
Add a ment  | 

2 Answers 2

Reset to default 5

This is what I ended up doing.

public render(){
  let htmlText = //The string above
  let doc = new DOMParser().parseFromString(htmlRender,'text/html');
  let xpathNode = doc.evaluate("/html/body/ul/li[1]/a[1]", doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); 
  const highlightedNode = xpathNode.singleNodeValue.innerText;
  const textValuePrev = highlightedNode.slice(0, char_start);
  const textValueAfter = highlightedNode.slice(char_end, highlightedNode.length);
  xpathNode.singleNodeValue.innerHTML = `${textValuePrev}
                                         <span class='pt-tag'>
                                         ${highlightedNode.slice(char_start, char_end)}
                                         </span> ${textValueAfter}`;
  return(
    <h5> Display html data </h5>
    <div dangerouslySetInnerHTML={{__html: doc.body.outerHTML}} />
   )

Xpath is inherently cross ponent, and React ponents shouldn't know much about each other. Xpath also basically requires all of the DOM to be created in order to query it. I would render your ponent first, then simply mutate the rendered output in the DOM using the Xpath selector.

https://jsfiddle/69z2wepo/73860/

var HighlightXpath = React.createClass({
  ponentDidMount() {
     let el = document.evaluate(this.props.xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
     el.singleNodeValue.style.background = 'pink';
  },
  render: function() {
    return this.props.children;
  }
});

Usage:

<HighlightXpath xpath="html//body//div/p/span">
    ... app ...
</HighlightXpath>

Given the HTML as a string, the Xpath and offsets. I need to highlight the word.

In the below case I need to highlight Child 1

HTML text:

<html>
 <body>
       <h2>Children</h2>Joe has three kids:<br/>
       <ul>
        <li>
        <a href="#">Child 1 name</a>
        </li>
        <li>kid2</li>
        <li>kid3</li>
       </ul>
 </body>
</html>

XPATH as : /html/body/ul/li[1]/a[1]

Offsets: 0,7

Render - I am using react in my app. The below is what I have done so far.

public render(){
  let htmlText = //The string above
  let doc = new DOMParser().parseFromString(htmlRender,'text/html');
  let ele = doc.evaluate("/html/body/ul/li[1]/a[1]", doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); //This gives the node itself
  let spanNode = document.createElement("span");
  spanNode.className = "highlight";

  spanNode.appendChild(ele);
  // Wrapping the above node in a span class will add the highlights to that div
  //At this point I don't know how to append this span to the HTML String
  return(
    <h5> Display html data </h5>
    <div dangerouslySetInnerHTML={{__html: htmlText}} />
   )

I want to avoid using jquery. Want to do in Javascript(React too) if possible!

Edit:

So if you notice the Render function it is using dangerouslySetHTML. My problem is I am not able manipulate that string which is rendered.

Given the HTML as a string, the Xpath and offsets. I need to highlight the word.

In the below case I need to highlight Child 1

HTML text:

<html>
 <body>
       <h2>Children</h2>Joe has three kids:<br/>
       <ul>
        <li>
        <a href="#">Child 1 name</a>
        </li>
        <li>kid2</li>
        <li>kid3</li>
       </ul>
 </body>
</html>

XPATH as : /html/body/ul/li[1]/a[1]

Offsets: 0,7

Render - I am using react in my app. The below is what I have done so far.

public render(){
  let htmlText = //The string above
  let doc = new DOMParser().parseFromString(htmlRender,'text/html');
  let ele = doc.evaluate("/html/body/ul/li[1]/a[1]", doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); //This gives the node itself
  let spanNode = document.createElement("span");
  spanNode.className = "highlight";

  spanNode.appendChild(ele);
  // Wrapping the above node in a span class will add the highlights to that div
  //At this point I don't know how to append this span to the HTML String
  return(
    <h5> Display html data </h5>
    <div dangerouslySetInnerHTML={{__html: htmlText}} />
   )

I want to avoid using jquery. Want to do in Javascript(React too) if possible!

Edit:

So if you notice the Render function it is using dangerouslySetHTML. My problem is I am not able manipulate that string which is rendered.

Share Improve this question edited Mar 20, 2017 at 4:18 suprita shankar asked Mar 18, 2017 at 3:01 suprita shankarsuprita shankar 1,5892 gold badges19 silver badges50 bronze badges 2
  • It may be just me, but it's not very clear what exactly you need to acplish? Do you need to simply modify the value of htmlText before you put it in dangerouslySetInnerHtml? – hazardous Commented Mar 21, 2017 at 8:15
  • Is this your actual code snippet or just an example? Lot of stuff is puzzling here, there is the public before render, then you are trying to nest html inside a div. Could you please share a more plete code? git repo would be preferable. – hazardous Commented Mar 21, 2017 at 8:17
Add a ment  | 

2 Answers 2

Reset to default 5

This is what I ended up doing.

public render(){
  let htmlText = //The string above
  let doc = new DOMParser().parseFromString(htmlRender,'text/html');
  let xpathNode = doc.evaluate("/html/body/ul/li[1]/a[1]", doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); 
  const highlightedNode = xpathNode.singleNodeValue.innerText;
  const textValuePrev = highlightedNode.slice(0, char_start);
  const textValueAfter = highlightedNode.slice(char_end, highlightedNode.length);
  xpathNode.singleNodeValue.innerHTML = `${textValuePrev}
                                         <span class='pt-tag'>
                                         ${highlightedNode.slice(char_start, char_end)}
                                         </span> ${textValueAfter}`;
  return(
    <h5> Display html data </h5>
    <div dangerouslySetInnerHTML={{__html: doc.body.outerHTML}} />
   )

Xpath is inherently cross ponent, and React ponents shouldn't know much about each other. Xpath also basically requires all of the DOM to be created in order to query it. I would render your ponent first, then simply mutate the rendered output in the DOM using the Xpath selector.

https://jsfiddle/69z2wepo/73860/

var HighlightXpath = React.createClass({
  ponentDidMount() {
     let el = document.evaluate(this.props.xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
     el.singleNodeValue.style.background = 'pink';
  },
  render: function() {
    return this.props.children;
  }
});

Usage:

<HighlightXpath xpath="html//body//div/p/span">
    ... app ...
</HighlightXpath>

本文标签: javascriptHighlighting when HTML and Xpath is givenStack Overflow