Does not append elements to the first tag

82 views Asked by At

function $(selector) {

    var resultObject = {
        append: function (element) {
            var parser = new DOMParser();
            var dos = parser.parseFromString(element, "text/html");

            var all = dos.getElementsByTagName("body")[0];
       
            var elemWhichAppend = document.getElementsByTagName(selector);

            var children = all.childNodes;
   
            for (var i = elemWhichAppend.length-1; i >=0; i--) {

                var msgContainer = document.createDocumentFragment();
                var children = all.childNodes;

                for (var child = 0; child < children.length; child++) {
                    var al = children[child];
                    msgContainer.appendChild(al);
                }
                insertAfter(msgContainer, elemWhichAppend[i]);
            }
        }
    }

    return resultObject;
}

function insertAfter(newNode, referenceNode) {
    referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
<!DOCTYPE html>
<html>
  <head>
    <title></title>
 <meta charset="utf-8" />
    <script src="jqueryjs.js"></script>
  </head>
  <body>
    <h1 class="testing">APPEND</h1>
    <p>Hallo, ich bin ein P TAG </p>
    <h1 class="testing">APPEND2</h1>
    <p>BADGL</p>
    <input type="button" value="append tag/text " onclick="$('p').append('<ul><li>RIBA RIBI<ul><li>FRANK RIBERY</li></ul></li></ul> <h1>NIGOGOG</h1> messi ist scheiße');" />
  </body>
</html>

Run code snipped. As you can see the function adds only to the last p element the tags. And forgets the 'messi ist scheiße'. I tried a lot of thinks but I am not able to find my bug. Is it because the 'messi ist scheiße' a text is?

4

There are 4 answers

3
dtdesign On

Wrapping (messi ist scheiße) in a div, p or h1 tag will do the trick.

<input type="button" value="append tag/text " onclick="$('p').append('<ul><li>RIBA RIBI<ul><li>FRANK RIBERY</li></ul></li></ul> <h1>NIGOGOG</h1> <p>messi ist scheiße</p>');" />
13
Sabir On

On testing this a little in JS fiddle, i found that as you loop through the child elements, for some reason the variable you declared as 'all' seems to be dissappearing, or at least deteriorating in nature to the extent that it doesn't contain any child elements on the second loop, and so does not go through the Child-elements loop the second time around.

One thing that seemed to improve performance was redefining all and dos at the top of the loop:

for (var i = elemWhichAppend.length-1; i >=0; i--) {
     var dos = parser.parseFromString(element, "text/html");
     var all = dos.getElementsByTagName("body")[0];
     var msgContainer = document.createDocumentFragment();
     ...

This should help, as it certainly solved the JSFiddle I was on. I'm not certain why the 'all' variable is changing in nature exactly, but it changes - as i saw from the log - as soon as you perform this line:

msgContainer.appendChild(al);

I imagine it happens after you perform that line because that line actually accesses the 'document' object and causes it to change (since msgContainer is derived from document object).

Also, you would probably have to include the 'messi ist Shiese' into a html tag, as the line

var dos = parser.parseFromString(element, "text/html");

This line seems to only find the HTML elements in the element you've provided. You can check this by trying to console.log the 'child' element itself, and you will see that when you include the 'messi ist sheise' part into a tag, it will appear, but it won't appear when it's not in a tag.

for (var child = 0; child < children.length; child++) {
     var al = children[child];
     console.log(children[child]);
     msgContainer.appendChild(al);
}
3
Biagio Boi On

You've missed a "" near getElementsByTagName

1
andi On

You made this way more complicated than it needs to be. Just make the append function append your string onto the element's innerHTML.

function $(selector) {
    var resultObject = {
        append: function (element) {
            var elemWhichAppend = document.getElementsByTagName(selector);
            for (var i = elemWhichAppend.length-1; i >=0; i--) {
                elemWhichAppend[i].innerHTML += element;
            }
        }
    }
    return resultObject;
}
<h1 class="testing">APPEND</h1>
<p>Hallo, ich bin ein P TAG </p>
<h1 class="testing">APPEND2</h1>
<p>BADGL</p>
<input type="button" value="append tag/text " onclick="$('p').append('<ul><li>RIBA RIBI<ul><li>FRANK RIBERY</li></ul></li></ul> <h1>NIGOGOG</h1> messi ist scheiße');" />