1

I am trying to write a function to mirror the insertAdjacentHTML dom method Element.insertAdjacentHTML and here it is

function insertAdjacent(targetElement) {
'use strict';
return {
    insertAfter: function (newElement, targetElement) {
        var parent = targetElement.parentNode;
        if (parent.lastChild === targetElement) {
            parent.appendChild(newElement);
        } else {
            parent.insertBefore(newElement, targetElement.nextSibling);
        }
    },

    insertAtBegin: function (newElement) {
        var fChild = targetElement.firstChild;
        if (!fChild) {
            targetElement.appendChild(newElement);
        } else {
            targetElement.insertBefore(newElement, fChild);
        }
    },

    insertAtEnd: function (newElement) {
        var lChild = targetElement.lastChild;
        if (!lChild) {
            targetElement.appendChild(newElement);
        } else {
            this.insertAfter(newElement, targetElement.lastChild);
        }
    }
};
}

The function works fine when you insert two different element nodes at the beginning and the end as shown here. But the problem comes when i try to insert the same element node at the beginning and the end as shown here. It only inserts the element node at the end and not at both the beginning and end. What could be causing this issue? Thank you

kellymandem
  • 1,709
  • 3
  • 17
  • 27

2 Answers2

2

Because One element can't be insert in two place at the same time, if you want to do it, at each function's first line, add newElement = newElement.cloneNode(true); I've altered your 2nd jsfiddle, have a look.

fuyushimoya
  • 9,715
  • 3
  • 27
  • 34
2

The problem was that you are using the exact same element, which can only be placed in one place...

If you clone it, there shouldn't be a problem. Here's your second fiddle exactly as you have written it, with an extra deepCopy function from this answer:

adjacentInsert.insertAtBegin(deepCopy(span1));
Community
  • 1
  • 1
Armfoot
  • 4,663
  • 5
  • 45
  • 60
  • I can promise this @Armfoot, i didn't understand the `deepCopy` function but thanks anyway – kellymandem Jun 25 '15 at 10:06
  • @kellymandem no problem, a deep clone will help with more complex elements than the one you currently have... If you by chance want to cover Arrays, Dates or others, you can use that function without worrying about importing specific stuff for doing that (e.g. jQuery). It basically covers a lot of cases and normally `Object.create` is defined, so [you can ignore the last create function](https://jsfiddle.net/s5sje3pL/5/) :) – Armfoot Jun 25 '15 at 10:18
  • 2
    @kellymandem And by the way, if you prefer just using the `cloneNode` like in _fuyushimoya_'s answer, you only need to use it one time (instead of 3) [like this `adjacentInsert.insertAtEnd(span1.cloneNode(true));`](https://jsfiddle.net/s5sje3pL/9/). – Armfoot Jun 25 '15 at 10:33
  • 1
    Thank you @Armfoot, that is a neat little trick. By the way i have just read up on the cloneNode method on the [mdn](https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode) and it also copies the attributes too, so how can you prevent elements with ids from being inserted more than once in the DOM. – kellymandem Jun 25 '15 at 10:50
  • 1
    @kellymandem for that you would need to change them case by case, meaning: [`var clonedEl = span1.cloneNode(true); clonedEl.id='myNewClonedID';`](http://stackoverflow.com/questions/1650299/how-do-i-change-the-id-of-a-html-element-with-javascript) or using jQuery: [`$("#span1ID").clone().prop('id','myNewClonedID')`](http://stackoverflow.com/questions/8612498/is-it-possible-to-clone-html-elements-in-jquery-with-new-id-and-name) – Armfoot Jun 25 '15 at 11:18
  • Good stuff @Armfoot, i get now – kellymandem Jun 25 '15 at 11:25