简体   繁体   中英

Insert span in a dom element without overwrite child nodes?

I have an HTML article with some annotations that I retrieve with SPARQL queries. These annotations refer to some text in the document, and I have to highlight this text (wrapping it in a span).

I had already asked how to wrap text in a span, but now I have a more specific problem that I do not know how to solve. The code I wrote was:

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);

Where:

v[4]["element"] is the id of the parent element of the annotation

v[5]["start"] is the position of the first character of the annotation

v[6]["end"] is the position of the last character of the annoation

Note that start and end don't consider html tags.

In fact my mistake consists in extracting data from the node with the text() method (to be able to go back to the correct position of the annotation) and put back with the html() method; but in this manner if parent node has children nodes, they will be lost and overwritten by simple text.

Example: having an annotation on '2003'

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

It becomes:

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

I think I should work with nodes instead of simply extract and rewrite the content, but I don't know how to identify the exact point where to insert the annotation without considering html tags and without eliminating child elements.

I read something about the jQuery .contents() method, but I didn't figure out how to use it in my code.

Can anyone help me with this issue? Thank you

EDIT: Added php code to extract body of the page.

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);
    }

}

Instead of doing all these, you can either use $(el).append() or $(el).prepend() for inserting the <span> tag!

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

Or, If I understand correctly, you wanna wrap the final 2003 with a span.annotation right? If that's the case, you can do:

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

Fiddle:

 $(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> 

At the end my solution is in this Fiddle.

Generalizing:

        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);

Hope it could help someone else.

Note: This don't check if two or more annotations refers to the same node, I'm working on it right now.

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