简体   繁体   中英

Replace part of a string with anchor tag

I have a sentence: "This is a sentence with a link1, also it has link2" It is in p tag. I also have data when it starts and when it ends, respectively:

[{ start: 26, end: 31 }, { start: 45, end: 50 }]

Is it possible to replace these parts of the sentence with anchor tags having upper data available. As a result it would be a something like this:

<p>This is a sentence with a <a>link1</a>, also it has <a>link2</a></p>

Thanks!

Building a string of HTML and/or using dangerouslySetInnerHTML is not the correct solution here. To solve this the "React way," consider that this structure:

<p>This is a sentence with a <a>link1</a>, also it has <a>link2</a></p>

...could be generated with this React component (this is more verbose than necessary, just for clarity's sake):

const LinkText = () => {
  const parts = [
    'This is a sentence with a ',
    <a>{'link1'}</a>,
    ', also it has ',
    <a>{'link2'}</a>,
  ];
  return <p>{parts}</p>;
};

With that in mind, the question is this: How do we generate the parts array from a string and an array of link positions? The solution is to iterate over the array of link positions and, in each iteration, push onto the array 1) The "non-link" text between the previous link position's end (or the start of the string), and 2) an <a> containing the current link position's start and end . A simple, working implementation looks like this:

 const LinkText = ({ text, linkPositions }) => { const parts = []; let currentIndex = 0; linkPositions.forEach(({ start, end }) => { if (currentIndex < start) { parts.push(text.slice(currentIndex, start)); } parts.push(<a>{text.slice(start, end)}</a>); currentIndex = end; }); if (currentIndex < text.length - 1) { parts.push(text.slice(currentIndex)); // Remaining text after the last link } return <p>{parts}</p>; }; const text = 'This is a sentence with a link1, also it has link2'; const links = [{ start: 26, end: 31 }, { start: 45, end: 50 }]; ReactDOM.render(<LinkText text={text} linkPositions={links}/>, document.querySelector('div')); 
 a{color:blue} 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div></div> 

The best way to do that is using IDs and JS.

So, for example, your HTML would look like this:

<p>This is a sentence with a <a id="linkOne">link1</a>, also it has <a id="linkTwo">link2</a></p>

And then your JS would call this:

document.getElementById("linkOne").href = "http://linkOne.com"
document.getElementById("linkTwo").href = "http://linkTwo.com"

You can achieve that with str.replace with a regex.

as @Dupocas said, React will escape html tags, so you will need to use dangerouslySetInnerHTML

 const str = 'This is a sentence with a link1, also it has link2'; const result = str.replace(/link(\\d)/g, (match, linkId) => { return `<a href="${linkId}">${match}</a>`; }); console.log(result); 

You can use this snippet to replace the text at the specific places into links. I have sorted it in a descending order based on the start since changing it from the end of the string is easier.

 document.getElementById("convert").addEventListener("click", convertLinks); addEventListener function convertLinks() { var pTag = document.getElementById("test") var text = pTag.innerHTML posData = [{ start: 26, end: 31 }, { start: 45, end: 50 }] posData = posData.sort(function(pos1, pos2) { return pos2.start - pos1.start }) for (pos of posData) { text = replaceLink(text, pos) } pTag.innerHTML = text; } function replaceLink(text, pos) { return text.slice(0, pos.start) + "<a>" + text.slice(pos.start, pos.end) + "</a>" + text.slice(pos.end) } 
 a { color: blue } 
 <p id="test">This is a sentence with a link1, also it has link2</p> <button id="convert"> Convert Links </button> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM