whatTheHack whatTheHack - 7 months ago 8
Javascript Question

How to sequentially .append() created elements to the previously added element

The code

JavaScript:

var recurringF = (function(){
this.$el = $("#target");
this.arg = arguments[0];
this.spl = (!_.isEmpty(this.arg)) ? this.arg.split(" ") : false;
if(this.spl){
for(var i=0;i<this.spl.length;i++){
if(i===0){
this.$el.append(document.createElement(this.spl[i]));
}else{
this.$el.children().last().append(document.createElement(this.spl[i]));
}
}
}
return {
"$":this.$el
}
});

var t = new recurringF("div h1 span");


HTML-Body:

<body>
<div id="target"></div>
</body>


The Goal

I'd like to append elements sequentially to an parent element $("#target") so that the end result in the HTML is the following:

<body>
<div id="target">
<div>
<h1>
<span></span>
</h1>
</div>
</div>
</body>


The loop does not append the created elements to the the last appended element, but to the in loop cycle 1 created element 'div' like the following:

<div id="target">
<div>
<h1></h1>
<span></span>
</div>
</div>


What am I missing?

Answer

You can try this:

For one thing there does not seem to be a reason to create a new object in your example as it just returns the target.

You can try this instead:

var targetElement = document.getElementById('target');
function recurseElement(elementString, target) {
    var currentElement = target;
    var domElement;
    var elements = elementString ? elementString.split(' ') : [];
    var elementLength = elements.length;
    var index = 0;

    for (index; index < elementLength; ++index) {
        domElement = document.createElement(elements[index]);
        currentElement.appendChild(domElement);
        currentElement = domElement;
    }

    return target;
}

or in es6:

const recurseElement = (elementString, target) => {
    const elements = elementString.split(' ');
    elements.forEach(function(ele) {
        const domElement = document.createElement(ele); // create the element
        target.appendChild(domElement); // append to the target
        target = domElement; // this element is the new target
    });
}

So now you can use it like so:

recurseElement('div h1 span', document.getElementById('target'));

const recurseElement = (elementString, target) => {
  const elements = elementString.split(' ');
  elements.forEach(function(ele) {
    const domElement = document.createElement(ele); // create the element
    target.appendChild(domElement); // append to the target
    target = domElement; // this element is the new target
  });
};

recurseElement('div h1 span', document.getElementById('target'));
#target div {
  background: green;
  height: 16px; width: 128px; padding: 10px;
}

#target div h1 {
  background: red;
  height: 16px; width: 64px; padding: 10px;
}

#target div h1 span {
  background: purple; display: block;
  height: 16px; width: 32px; padding: 10px;
}
<div id="target"></div>

It should be noted that arrow functions are available for Chrome 45+, Firefox 22.0+, Edge, and Opera. They do not work in IE or Safari. Or they will work if you have a transpiler (like babel)

Comments