【问题标题】:"jQuery way" to replace just a text node with a mix of HTML and text?“jQuery方式”用HTML和文本的混合替换一个文本节点?
【发布时间】:2012-10-02 20:01:28
【问题描述】:

在我的网络浏览器用户脚本项目中,我只需要替换一个文本节点,而不会影响与文本相同的父节点下的其他 HTML 元素。而且我需要用多个节点替换它:

<div id="target"> foo / bar; baz<img src="/image.png"></div>

需要成为:

<div id="target"> <a href="#">foo</a> / <a href="#">bar</a>; <a href="#">baz</a><img src="/image.png"></div>

我知道 jQuery 对文本节点的支持并不多。我知道我可以使用直接 DOM 调用而不是 jQuery。而且我知道我可以做类似$('#target').html(my new stuff + 我不想改变的东西)。另请注意,我想保留初始空间,这本身似乎很棘手。

我想在这里问专家的是,有没有最惯用的 jQuery 方法来做到这一点?

【问题讨论】:

  • 你怎么知道在哪里分解替换文本?
  • @j_mcnally:假设我们有“某种方式”来生成替换文本/HTML。在我的实际项目中,我将原始文本解析为一些对象,然后我使用这些对象生成基本相同的文本,但将某些单词更改为链接。
  • 我不知道任何 jQuery 解决方案;但我确实写了一个高亮功能,它的功能接近你想要完成的:jsfiddle.net/rkw79/5cCuc
  • @rkw:是的,这绝对是一个相关的问题。

标签: jquery dom-manipulation replacewith


【解决方案1】:

您基本上想用新内容替换第一个子节点(文本节点)。你需要http://api.jquery.com/replaceWith/

// Text node we want to process and remove
var textNode = $("#target").contents().first();
// Break the text node up
var parts = textNode.text().split(/\s/);
// Put links around them
var replaceWith = "";
for (var i =0; i < parts.length;i++) {
    replaceWith += "<a href='http://www.google.com'>"  + escapeHTML(parts[i]) + "</a> ";
}
// Replace the text node with the HTML we created
textNode.replaceWith(replaceWith);

function escapeHTML(string) {
  return string.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="target">example, handles escaping properly, you should see an ampersand followed by "amp;" here: &amp;amp; <img src="/foobar.png"></div>

http://jsfiddle.net/NGYTB/1/

【讨论】:

  • 好吧,新的 HTML 不是纯粹基于空白与非空白,但这种方法绝对是非常好的!
  • @hippietrail 我怎么知道你打算如何打破它?这只是一个简单明了的示例,因此您可以根据需要对其进行修改。相关部分是可以访问文本节点,并用您将要提出的 HTML 替换
  • 对不起,这不应该是投诉,只是对其他阅读者的评论。除非出现真正令人惊讶的事情,否则我会接受您的回答,所以不要担心(-:
【解决方案2】:

试试这个方法

// nodeType = 1 corresponds to element node
   // You are filtering everything out other than that and 
   // removing the textnodes from it..
   // contents() will get everything including the text
    ​$('#target'​).contents().filter(function() {
        return this.nodeType != 1; 
    }).remove();

   // Then you are prepending the div with the html  that needs to 
   //  replaced with the text...
    $('#target').prepend('<a href="#">mixed</a> text <a href="#">and</a> HTML');
   // This makes sure you do not touch the initial img element inside the div

如果您不想删除特定的节点类型,可以添加其他节点类型 CHECK FIDDLE​

【讨论】:

  • 这行得通。我想这不是一个非常通用的方法,但它似乎是一个稍微超出 jQuery 范围的问题域,并且这个 is 惯用的 jQuery。
【解决方案3】:

试试这个..编辑的版本

$('#target').html('<a href="#">mixed</a> text <a href="#">and</a> HTML' + $('#target').html());

【讨论】:

  • 但这会导致some text&lt;img src="/image.png"&gt;&lt;a href="#"&gt;mixed&lt;/a&gt; text &lt;a href="#"&gt;and&lt;/a&gt; HTML
  • 不,那行不通。对.html() 的调用返回旧的HTML包括旧的文本节点。所以基本上它最终会添加新的东西,而不是用新的东西替换旧的东西。
  • 好吧,我还没有代码。我有来自我正在为其编写用户脚本的网站的 HTML,我只是直接在 JavaScript 控制台中尝试各种方法。如果您真的需要查看一些我正在尝试从该站点转换的 HTML,我们可以在 SE 聊天室中进行。如果有帮助的话,我已经更新了我的示例 HTML,看起来更像我的问题。
猜你喜欢
  • 1970-01-01
  • 2011-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-04
  • 2018-12-04
  • 1970-01-01
相关资源
最近更新 更多