简体   繁体   English

使用JavaScript在文本中插入链接而不会替换div的全部内容

[英]Using javascript to insert links in text WITHOUT replacing entire content of div

I'm writing a widget that searches for specific keywords in a specified "#content" div. 我正在编写一个小部件,该小部件在指定的“ #content” div中搜索特定的关键字。

Here is how I set it up originally using jQuery (simplified version): 这是我最初使用jQuery(简体版)进行设置的方法:

  • set a variable equal to the html of the content: var content = $('content').html(); 设置一个与内容的html相等的变量: var content = $('content').html();
  • use some regexes to replace certain keywords with <a href='link.html'>keyword</a> 使用一些正则表达式将某些关键字替换为<a href='link.html'>keyword</a>
  • replace the html of the content div with the new content: $('content').html(content); 用新内容替换内容div的html: $('content').html(content);

This works for the most part, but the problem occurs when the "#content" div contains javascript. 这在大多数情况下都有效,但是当“ #content” div包含javascript时,就会出现问题。 When I set $('content').html(content) , it re-runs any javascript code contained in the $('content') div, which can cause errors. 当我设置$('content').html(content) ,它将重新运行$('content') div中包含的所有JavaScript代码,这可能会导致错误。 Since this is a widget that I'm writing to work on any site, I don't have control over the content div, and whether there will be any javascript in it. 由于这是我正在编写的可在任何网站上使用的小部件,因此我无法控制内容div,以及其中是否包含任何JavaScript。

My questions is, is there a way to replace JUST the keywords with <a href='link.html'>keyword</a> , WITHOUT replacing the entire content of the div? 我的问题是,有没有办法用<a href='link.html'>keyword</a>替换关键字,而<a href='link.html'>keyword</a>替换div的全部内容?

My questions is, is there a way to replace JUST the keywords with <a href='link.html'>keyword</a> , WITHOUT replacing the entire content of the div? 我的问题是,有没有办法用<a href='link.html'>keyword</a>替换关键字,而<a href='link.html'>keyword</a>替换div的全部内容?

Yes. 是。 It's one of the (few) places where jQuery doesn't really offer you much. 这是jQuery确实不能为您提供很多东西的(少数)地方之一。

Down at the raw DOM API level, though, the Text node containing the actual text of the element has a splitText function with which you can split the node into two adjacent nodes at a specific location. 但是,从原始DOM API级别开始,包含元素实际文本的Text节点具有splitText函数 ,您可以使用该函数将节点拆分为特定位置的两个相邻节点。 So in your case, you'd split at the beginning of the word and then again after the end of it, then wrap that middle Text node in a new anchor. 因此,在您的情况下,您将在单词的开头拆分,然后在单词的末尾拆分,然后将中间的Text节点包装在新的锚点中。

Here's an example: Live copy | 这是一个示例: 实时复制 | source 资源

HTML: HTML:

<input type="button" id="theButton" value="Make it a link">
<p id="example">This is the example paragraph.</p>

JavaScript: JavaScript:

jQuery(function($) {

  $("#theButton").click(function() {
    var targetWord, p, textNode, index, nodeWord, nodeAfter;

    // Our target word
    targetWord = "example";

    // Get the paragraph using jQuery; note that after we
    // use jQuery to get it (because it fixes getElementById for
    // us on older versions of IE), we then use [0] to access
    // the *raw* `p` element.
    // Then get the text node from it.
    p = $("#example")[0];
    textNode = p.firstChild;

    // Find our text in the text node
    index = textNode.nodeValue.indexOf(targetWord);
    if (index !== -1) {
      // Split at the beginning of the text
      nodeWord = textNode.splitText(index);

      // Split the new node again at the end of the word
      nodeAfter = nodeWord.splitText(targetWord.length);

      // Insert a new anchor in front of the word
      anchor = document.createElement('a');
      anchor.href = "http://stackoverflow.com";
      p.insertBefore(anchor, nodeWord);

      // Now move the word *into* the anchor
      anchor.appendChild(nodeWord);
    }
  });

});

Naturally there are some things you'd want to do to improve that: 当然,您需要做一些事情来改善它:

  • Handle the index === 0 case without creating an empty text node at the beginning of the parent element. 处理index === 0情况下,不要在父元素的开头创建空文本节点。 (Harmless, but less than ideal.) (无害,但不理想。)
  • Handle the case where the word is at the very end of the parent, so you don't end up with an empty text node there. 处理单词在双亲的最末尾的情况,这样您就不会在那里出现一个空的文本节点。 (Again.) (再次。)

you can replace only keywords without replacing all content like this, 您只能替换关键字而不替换所有此类内容,

function keywordconvert(str, p1, offset, s)  {
      return "<a href=\"link?t="+encodeURIComponent(p1)+"\">"+p1+"</a>";
}

function search(keyword) {
   var content = document.getElementById("content");
   var re = new RegExp("("+keyword+")","g");
  content.innerHTML = content.innerHTML.replace(re, keywordconvert);
}

USAGE 用法

search("keyword");

​​

DEMO 演示

Yes, but you would have to loop through all text nodes manually. 是的,但是您必须手动遍历所有文本节点。

Far easier would be to strip <script> tags first, because once they have been run they are not needed on the page (everything is kept in memory). 首先剥离<script>标记会容易得多,因为一旦运行它们,页面上就不需要它们了(所有内容都保存在内存中)。

$('#content script').remove();

That will remove the scripts from the #content element, then you can run your existing replace code without problems. 这将从#content元素中删除脚本,然后您可以运行现有的替换代码而不会出现问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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