I'm editing a rather primitive forum, and it won't let me modify the HTML. I can only edit the CSS. So, I want to see if it would be possible to add a <div class""></div> in the HTML with JavaScript that encloses more of the existing elements.
The current HTML is as follows:
<div class="details">
<div class="avatar">
<img src="https://i.imgur.com/1r7oGBt.png"></div>
<p><span class="u_title">None</span>
<span class="u_rank"></span></p>
<dl class="u_group"><dt>Group</dt>
<dd>User</dd>
</dl>
<dl class="u_posts"><dt>Messages</dt>
<dd>52</dd>
</dl>
<dl class="u_scoresystem rep_zero"><dt>Score System</dt>
<dd>0</dd>
</dl>
<dl class="u_status"><dt>Estado</dt>
<dd>Anónimo</dd>
</dl>
</div>
And I would like it to be something like this, i.e. using <div class="overlay"></div>:
<div class="details">
<div class="avatar">
<img src="https://i.imgur.com/1r7oGBt.png"></div>
<div class="overlay">
<p><span class="u_title">None</span>
<span class="u_rank"></span></p>
<dl class="u_group"><dt>Group</dt>
<dd>User</dd>
</dl>
<dl class="u_posts"><dt>Messages</dt>
<dd>52</dd>
</dl>
<dl class="u_scoresystem rep_zero"><dt>Score System</dt>
<dd>0</dd>
</dl>
<dl class="u_status"><dt>Estado</dt>
<dd>Anónimo</dd>
</dl>
</div>
</div>
Is this possible?
That's easy:
details.document.createElement.Don't try to solve the problem by copying some HTML strings and using innerHTML as that will lose you any event listeners potentially attached to the elements you wrap.
const details = document.querySelectorAll('.details');
for (const detail of details) {
const [ first, ...childrenToWrap ] = [...detail.children];
const div = document.createElement('div');
div.className = 'overlay';
detail.append(div);
div.append(...childrenToWrap);
}
.overlay {
background-color: orange;
}
<div class="details">
<div class="avatar">
<img src="https://i.imgur.com/1r7oGBt.png"></div>
<p><span class="u_title">None</span>
<span class="u_rank"></span></p>
<dl class="u_group"><dt>Group</dt>
<dd>User</dd>
</dl>
<dl class="u_posts"><dt>Messages</dt>
<dd>52</dd>
</dl>
<dl class="u_scoresystem rep_zero"><dt>Score System</dt>
<dd>0</dd>
</dl>
<dl class="u_status"><dt>Estado</dt>
<dd>Anónimo</dd>
</dl>
</div>
It is very easy. Use document.createElement to create the element, add attributes, and append it to the selected element.
var myEl = document.createElement("div");
// Use "className" because JavaScript "class" is a reserved keyword.
myEl.className = "myClass";
// Append it
document.querySelector("div").appendChild(myEl);
Working live example:
var myEl = document.createElement("div");
// Use "className" because JavaScript "class" is a reserved keyword.
myEl.className = "myClass";
// Append it
document.querySelector("div").appendChild(myEl);
if (!!myEl) {
myEl.textContent = "You can append other attributes too!";
}
<div>
</div>
You can add it as a parent element too:
var currentEl = document.querySelector("div");
currentEl.outerHTML = `<div class="myClass">${currentEl.outerHTML}</div>`;
You can append many other attributes too.
Read more about createElement at Document.createElement().
I think you need something like this:
let messages = 52;
let score = 0;
document.body.insertAdjacentHTML('afterbegin',`
<div class="details">
<div class="avatar">
<img src="https://i.imgur.com/1r7oGBt.png"></div><div class="overlay">
<p><span class="u_title">None</span>
<span class="u_rank"></span></p>
<dl class="u_group"><dt>Group</dt><dd>User</dd></dl>
<dl class="u_posts"><dt>Messages</dt><dd>${messages}</dd></dl>
<dl class="u_scoresystem rep_zero"><dt>Score System</dt><dd>${score}</dd></dl>
<dl class="u_status"><dt>Estado</dt><dd>Anónimo</dd></dl></div></div>
`);
In the above code, as you can see, you can insert messages and score dynamically to the string and also you can add the HTML dynamically using JavaScript to the body of your html document.