Reputation: 35
Below is a code snippet of a function that creates and appends div HTML objects. The function is called from another function which appends additional elements to it.
I'm finding myself writing similar code as whats illustrated below. I know there has to be another more efficient way writing this code. What dry design pattern should I using? Is the object notation better for something like this? Examples would be great.
function create_element_container(){
var newElement = document.createElement('div'); //create container element
newElement.className = 'dropped'; //add classes to container element
var controllerContainer = document.createElement('div');
controllerContainer.className = 'drop-element-controls';
newElement.appendChild(controllerContainer);//Append controller container to main div
var controller_left = document.createElement('div');
controller_left.className = 'drop-move-controller';
controllerContainer.appendChild(controller_left);
var controller_left_move = document.createElement('div');
controller_left_move.className = 'drop-move';
controller_left.appendChild(controller_left_move);
var controller_left_icon = document.createElement('span');
controller_left_icon.className = 'fa fa-question fa-lg';
controller_left_move.appendChild(controller_left_icon);
controllerContainer.appendChild(controller_left); //Append controller Left
var controller_middle = document.createElement('div')
controller_middle.className = 'drop-sortable-controller';
controllerContainer.appendChild(controller_middle);
var controller_middle_sortable = document.createElement('div');
controller_middle_sortable.className = 'drop-sortable';
controller_middle.appendChild(controller_middle_sortable);
var controller_middle_icon = document.createElement('span');
controller_middle_icon.className = 'fa fa-arrows fa-lg';
controller_middle_sortable.appendChild(controller_middle_icon);
controllerContainer.appendChild(controller_middle); //Append controller Left
var controller_right = document.createElement('div')
controller_right.className = 'drop-remove-controller';
controllerContainer.appendChild(controller_right);
var controller_right_move = document.createElement('div');
controller_right_move.className = 'drop-remove';
controller_right.appendChild(controller_right_move);
var controller_right_icon = document.createElement('span');
controller_right_icon.className = 'fa fa-remove fa-lg';
controller_right_move.appendChild(controller_right_icon);
return newElement;
}
Upvotes: 2
Views: 1855
Reputation: 130155
It depends how many times it would run. if not many, then I would prepare a string of DOM and just use innerHTML
to put everything in some container. this would be more readable and maintainable.
function create_element_container(){
var elm, template;
elm = document.createElement('div'); //create container element
elm.className = 'dropped';
template = '<div class="something another"> \
<span></span> \
</div> \
<span class="foo"></span>';
// this makes our template text into a real DOM elements
elm.innerHTML = template;
return elm;
}
Upvotes: 0
Reputation: 74204
First I would write a createElement
function:
function createElement(tagName, className) {
var element = document.createElement(tagName);
element.className = className;
return element;
}
Next I would rewrite your create_element_container
function as follows:
function create_element_container() {
var newElement = createElement("div", "dropped");
var controllerContainer = newElement
.appendChild(createElement("div", "drop-element-controls"));
controllerContainer
.appendChild(createElement("div", "drop-move-controller"))
.appendChild(createElement("div", "drop-move"))
.appendChild(createElement("span", "fa fa-question fa-lg"));
controllerContainer
.appendChild(createElement("div", "drop-sortable-controller"))
.appendChild(createElement("div", "drop_sortable"))
.appendChild(createElement("span", "fa fa-arrows fa-lg"));
controllerContainer
.appendChild(createElement("div", "drop-remove-controller"))
.appendChild(createElement("div", "drop-remove"))
.appendChild(createElement("div", "fa fa-remove fa-lg"));
return newElement;
}
You can do this because parent.appendChild(child)
returns the child
element.
Upvotes: 1
Reputation: 74645
Your code consists of this repeated:
var controllerContainer = document.createElement('div');
controllerContainer.className = 'drop-element-controls';
newElement.appendChild(controllerContainer);
You might want to consider put-selector
. With put
:
var controllerContainer = put(newElement, 'div.drop-element-controls');
Doing that cuts down that function by 2/3rd. Then even combine the calls:
put(controllerContainer, 'div.drop-move-controller div.drop-move span.fa.fa-question.fa-lg <<');
Replaces:
var controller_left = document.createElement('div');
controller_left.className = 'drop-move-controller';
controllerContainer.appendChild(controller_left);
var controller_left_move = document.createElement('div');
controller_left_move.className = '';
controller_left.appendChild(controller_left_move);
var controller_left_icon = document.createElement('span');
controller_left_icon.className = 'fa fa-question fa-lg';
controller_left_move.appendChild(controller_left_icon);
controllerContainer.appendChild(controller_left); //Append controller Left
That cuts it down by 15/16th.
Another option is to just create the first element:
var newElement = document.createElement('div'); //create container element
newElement.className = 'dropped'; //add classes to container element
And then do:
newElement.innerHTML = '<div class="drop-move-controller"><div class="drop-move"><span class="fa fa-question fa-lg"></span></div></div>...';
Note that the HTML above only includes the div
with the class drop-move-controller
.
Upvotes: 1