I am trying to dynamically add elements created in JS to HTML, but would like to know the most efficient way of doing this. For example adding users to a list, the result would be:
<div id="user-list" style="display:flex; flex-direction:column">
<div id="user-1">
<span style="width:25%">PHOTO</span>
<span style="width:25%">name</span>
<span style="width:25%">surname</span>
<span style="width:25%">age</span>
</div>
<div id="user-2">
<span style="width:25%">PHOTO</span>
<span style="width:25%">name</span>
<span style="width:25%">surname</span>
<span style="width:25%">age</span>
</div>
</div>
I tried these 2 ways:
document.getElementById("user-list").innerHtml =
`<div id="user-${userId}">
<span style="width:25%">${userPhoto}</span>
<span style="width:25%">${userName}</span>
<span style="width:25%">${userSurname}</span>
<span style="width:25%">${userAge}</span>
</div>`
and
var user = document.createElement("div");
user.id = `user-${userId}`
var photo = document.createElement("span");
photo.setAttribute('style','width:25%')
photo.innerHTML = userPhoto;
var name = document.createElement("span");
name.setAttribute('style','width:25%')
name.innerHTML = userName;
var surname = document.createElement("span");
surname.setAttribute('style','width:25%')
surname.innerHTML = userName;
var age = document.createElement("span");
age.setAttribute('style','width:25%')
age.innerHTML = userAge;
user.appendChild(photo);
user.appendChild(name);
user.appendChild(surname);
user.appendChild(age);
document.getElementById("user-list").appendChild(user);
And it would loop creating and adding all the users (for example 20 users).
Which would be more efficient?
CodePudding user response:
I would use html <template>
tag.
You will have the elements and will be able to fill it with the data through the loop.
Example:
const template = document.querySelector('template')
const clone = template.content.cloneNode(1).firstElementChild
and you will be able to clone this template inside the loop for each entry, and will be able to select elements from it using:
clone.querySelector('<selector>')
when you have filled the template with data, you can add this clone element to the dom or any element. Like this:
document.appendChild(clone)
for more information check out html template tag with examples
CodePudding user response:
There multiple way you can modify the DOM. With document.createElement
, insertAdjacentHTML
, insertAdjacentText
, insertAdjacentElement
, cloneNode
or most easiest would be innerHTML
.
Adding static element that not going to interact with use any way, insertAdjacentHTML
, insertAdjacentText
, insertAdjacentElement
, innerHTML
would do great job for you.
But with document.createElement
you get more control over that DOM element. Allows you to add listeners, add and update attributes, and even remove elements from DOM in the easiest way.
Just a quick effort to show you, but definitely, you can use js more efficiently than this to manage elements within the document.
const employees=[{userId:"56146443",age:52,jobTitleName:"Developer",firstName:"Romin",lastName:"Irani",preferredFullName:"Romin Irani",employeeCode:"E1",region:"CA",phoneNumber:"408-1234567",emailAddress:"[email protected]"},{userId:"28949847",age:45,jobTitleName:"Developer",firstName:"Neil",lastName:"Irani",preferredFullName:"Neil Irani",employeeCode:"E2",region:"CA",phoneNumber:"408-1111111",emailAddress:"[email protected]"},{userId:"8934656",age:29,jobTitleName:"Program Directory",firstName:"Tom",lastName:"Hanks",preferredFullName:"Tom Hanks",employeeCode:"E3",region:"CA",phoneNumber:"408-2222222",emailAddress:"[email protected]"}];
function Cell(data){
this.render = () => {
const cell = document.createElement('td');
cell.append(data);
return cell;
}
}
function Row(data, deleteRow){
this.isDisabled = false;
this.handleDisableAction = () => {
this.isDisabled = true;
}
this.handleDeleteAction = () => {
deleteRow(data.userId);
}
this.render = () => {
const row = document.createElement('tr');
row.classList.add(data.age > 50? 'danger': 'normal');
row.append(...Object.values(data).map(d => {
const cell = new Cell(d).render();
cell.innerHTML = d;
return cell;
}))
const buttonDisable = document.createElement('button');
buttonDisable.textContent = this.isDisabled ? 'Enable' : 'Disable';
buttonDisable.classList.add(this.isDisabled ? 'disabled': 'enabled');
buttonDisable.addEventListener('click', this.handleDisableAction.bind(this));
row.append(new Cell(buttonDisable).render());
const buttonDelete = document.createElement('button');
buttonDelete.textContent = 'Delete';
buttonDelete.addEventListener('click', this.handleDeleteAction.bind(this));
row.append(new Cell(buttonDelete).render());
return row;
}
}
function Table(data){
this.handleDeleteRow = (rowId) => {
alert(`${rowId} will be deleted soon`);
}
this.render = () =>{
const table = document.createElement('table');
table.append(...data.map(d => {
const row = new Row(d, this.handleDeleteRow).render();
return row;
}))
return table;
}
}
document.body.append(new Table(employees).render());
table{
display: block;
width: 100%;
border-collapse: collapse;
}
tr.danger{
background-color: orange;
}