【问题标题】:Insert span in a dom element without overwrite child nodes?在 dom 元素中插入跨度而不覆盖子节点?
【发布时间】:2015-01-27 00:44:10
【问题描述】:

我有一篇带有一些注释的 HTML 文章,我使用 SPARQL 查询检索这些注释。这些注释引用了文档中的一些文本,我必须突出显示这些文本(将其包裹在一个 span 中)。

我已经问过如何在跨度中换行,但现在我有一个更具体的问题,我不知道如何解决。 我写的代码是:

var currentText = $("#"+v[4]["element"]+"").text();
var newText = currentText.substring(0, v[5]["start"]) + "<span class=' annotation' >" + currentText.substring(v[5]["start"], v[6]["end"]) + "</span>" + currentText.substring(v[6]["end"], currentText.length);
$("#"+v[4]["element"]+"").html(newText);

地点:

v[4]["element"]是注解的父元素的id

v[5]["start"]是注解第一个字符的位置

v[6]["end"]是注解最后一个字符的位置

请注意,startend 不考虑 html 标签。

事实上我的错误在于使用text()方法从节点中提取数据(以便能够回到注释的正确位置)并使用html()方法放回去;但是这样如果父节点有子节点,它们就会丢失并被简单的文本覆盖。

示例: 在“2003”上有注释

<p class="metadata-entry" id="k673f4141ea127b">
    <span class="generated" id="bcf5791f3bcca26">Publication date (<span class="data" id="caa7b9266191929">collection</span>): </span>
    2003
</p>

变成:

<p class="metadata-entry" id="k673f4141ea127b">
    Publication date (collection): 
    <span class="annotation">2003</span>
</p>

我认为我应该使用节点而不是简单地提取和重写内容,但我不知道如何在不考虑 html 标记和不消除子元素的情况下确定插入注释的确切点。

我阅读了一些关于 jQuery .contents() 方法的内容,但我不知道如何在我的代码中使用它。

谁能帮我解决这个问题?谢谢你

编辑:添加 php 代码以提取页面正文。

function get_doc_body(){
    if (isset ($_GET ["doc_url"])) {

        $doc_url = $_GET ["doc_url"];
        $doc_name = $_GET ["doc_name"];

        $doc = new DOMDocument;
        $mock_doc = new DOMDocument;

        $doc->loadHTML(file_get_contents($doc_url.'/'.$doc_name));
        $doc_body = $doc->getElementsByTagName('body')->item(0);
        foreach ($doc_body->childNodes as $child){
            $mock_doc->appendChild($mock_doc->importNode($child, true));
        }
        $doc_html = $mock_doc->saveHTML();
        $doc_html = str_replace ('src="images','src="'.$doc_url.'/images',$doc_html);

        echo($doc_html);
    }

}

【问题讨论】:

  • 您必须遍历所有文本节点。对于每个文本节点,使用单词作为分隔符将其拆分。迭代结果并生成一个文本节点,如果字符串不是单词和 span 元素,则它是一个。在原始文本节点之前插入新闻节点。最后删除原始文本节点。
  • 抱歉,我没能很好地理解您的回答,能否给我一个简短的 sn-p 应用于我的示例中的 &lt;p&gt; 元素?
  • 并非如此,这就是为什么这是评论,而不是答案。你需要以不同的方式开始。不要匹配元素节点并获取它们的“文本”,而是直接获取文本节点。文本节点包含您要突出显示的单词,需要用新节点替换。几年前我在 PHP 中实现了这个......
  • 好的,我在this 问题中找到了一个函数,并尝试在Fiddle 中使用它。变量是正确的,但似乎永远找不到文本节点,因此它永远不会更改内容。你能帮帮我吗?

标签: javascript jquery html dom nodes


【解决方案1】:

您可以使用$(el).append()$(el).prepend() 插入&lt;span&gt; 标签,而不是执行所有这些操作!

$("#k673f4141ea127b").append('<span class="annotation">2003</span>');

或者,如果我理解正确,你想用span.annotation 包装最后的2003 对吗?如果是这种情况,您可以这样做:

$("#k673f4141ea127b").contents().eq(1).wrap('<span class="annotation" />');

小提琴:

$(document).ready(function() {
  $("#k673f4141ea127b").contents().eq(1).wrap('<span class="annotation" />');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="metadata-entry" id="k673f4141ea127b">
    <span class="generated" id="bcf5791f3bcca26">Publication date (<span class="data" id="caa7b9266191929">collection</span>): </span>
    2003
</p>

【讨论】:

  • 使用append() 我在元素末尾添加&lt;span class="annotation"&gt;2003&lt;/span&gt;,这不是我想要的。我必须突出显示文档中已经存在的文本。此外,我可以在文本中间添加注释,因此我不能使用 append()。
  • @GioBact 查看更新后的答案。第二个。有小提琴的那个。
  • 好吧,我认为这是个好方法,但使用你的代码,结果是:&lt;p class="metadata-entry" id="k673f4141ea127b"&gt; &lt;span class="annotation"&gt;&lt;span class="generated" id="bcf5791f3bcca26"&gt;Publication date (&lt;span class="data" id="caa7b9266191929"&gt;collection&lt;/span&gt;): &lt;/span&gt;&lt;/span&gt; 2003 &lt;/p&gt; 我也试过eq(0),但在元素的开头插入一个空跨度
  • 让我说清楚。你想让空的 2003 用 .annotation 跨度包装吗?说是或否。
  • 你可以使用 JavaScript 的 .replace() 函数:yourText.replace('2003', '&lt;span class="annotation"&gt;2003&lt;/span&gt;');
【解决方案2】:

最后我的解决方案是在this Fiddle。

概括:

        var element = document.getElementById(id);
        var totalText = element.textContent;
        var toFindText = totalText.substring(start,end);
        var toReplaceText = "<span class='annotation'>"+toFindText+"</span>";
        element.innerHTML = element.innerHTML.replace(toFindText, toReplaceText);

希望它可以帮助别人。

注意:这不检查两个或多个注释是否引用同一个节点,我现在正在处理它。

【讨论】:

  • 在这种情况下,您知道开始和结束。 :(
猜你喜欢
  • 2015-10-07
  • 2020-03-16
  • 1970-01-01
  • 1970-01-01
  • 2016-10-12
  • 1970-01-01
  • 1970-01-01
  • 2015-06-16
  • 1970-01-01
相关资源
最近更新 更多