用锚标记替换字符串的一部分

时间:2019-05-24 18:58:24

标签: javascript reactjs

我有一句话:“这是一个带有link1的句子,它也具有link2” 它在p标签中。 我还分别拥有开始和结束时的数据:

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

是否可以用具有较高数据可用的锚标记替换句子的这些部分。结果就是这样:

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

谢谢!

4 个答案:

答案 0 :(得分:2)

构建HTML字符串和/或使用dangerouslySetInnerHTML在这里不是正确的解决方案。要解决“反应方式”问题,请考虑以下结构:

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

...可以使用此React组件生成(为了清楚起见,它比必需的更为冗长):

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

牢记这一点,问题是这样的:我们如何从字符串和链接位置数组生成parts数组?解决方案是遍历链接位置的数组,并在每次迭代中将其推入数组1)前一个链接位置的end(或字符串的开头)之间的“非链接”文本,以及2)一个<a>,其中包含当前链接位置的startend。一个简单有效的实现如下所示:

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>

答案 1 :(得分:-1)

最好的方法是使用ID和JS。

例如,您的HTML如下所示:

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

然后您的JS将其称为:

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

答案 2 :(得分:-1)

您可以使用带有正则表达式的str.replace来实现。

正如@Dupocas所说,React将转义html标签,因此您将需要使用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);

答案 3 :(得分:-1)

您可以使用此代码段将特定位置的文本替换为链接。由于从字符串的末尾更改它比较容易,因此我已根据其开头按降序对其进行了排序。

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>