querySelector
finds the first matching element in the document. So your code always adds elements to the first .myclass
in your document.
If you want to find all matching elements and update them, you use querySelectorAll
and loop through the results:
const list = document.querySelectorAll(".elementor-button-wrapper");
for (const el of list) {
// Create New Element
const newEl = document.createElement("span");
newEl.className = "cm-bg"; // *** See comment on question
const newEl2 = document.createElement("span");
newEl2.className = "cm-base"; // *** See comment on question
// Insert New Element AFTER an Element
el.before(newEl);
el.before(newEl2);
}
Live Example:
const list = document.querySelectorAll(".elementor-button-wrapper");
for (const el of list) {
// Create New Element
const newEl = document.createElement("span");
newEl.className = "cm-bg"; // *** See comment on question
const newEl2 = document.createElement("span");
newEl2.className = "cm-base"; // *** See comment on question
// Insert New Element AFTER an Element
el.before(newEl);
el.before(newEl2);
}
.cm-bg::after {
content: "cm-bg"
}
.cm-base::after {
content: "cm-base"
}
<div class="elementor-button-wrapper">
<a href="#" class="elementor-button-link" role="button">
<span class="elementor-button-content-wrapper">
<span class="elementor-button-text">Click here</span>
</span>
</a>
</div>
<div class="elementor-button-wrapper">
<a href="#" class="elementor-button-link" role="button">
<span class="elementor-button-content-wrapper">
<span class="elementor-button-text">Click here</span>
</span>
</a>
</div>
<div class="elementor-button-wrapper">
<a href="#" class="elementor-button-link" role="button">
<span class="elementor-button-content-wrapper">
<span class="elementor-button-text">Click here</span>
</span>
</a>
</div>
<div class="elementor-button-wrapper">
<a href="#" class="elementor-button-link" role="button">
<span class="elementor-button-content-wrapper">
<span class="elementor-button-text">Click here</span>
</span>
</a>
</div>
That relies on the NodeList
from querySelectorAll
being iterable, which it is in modern environments (and per specification). If you need to handle older environments, see my answer here for how to polyfill it. Or just use a for
loop:
for (let i = 0; i < list.length; ++i) {
const el = list[i];
// ...rest of loop body here...
}
Side note: Beware that no version of IE supports the before
method on ChildNode
. IE is actively being discontinued by Microsoft, but still has significant presence in large corporate or government installations.
FWIW, you can use insertAdjacentHTML
which is universally supported and lets you write the elements as HTML (if that's desireable):
const list = document.querySelectorAll(".elementor-button-wrapper");
for (const el of list) {
el.insertAdjacentHTML(
"beforestart",
"<span class=cm-bg></span><span class=cm-base></span>"
);
}
Or just use insertBefore
:
const list = document.querySelectorAll(".elementor-button-wrapper");
for (const el of list) {
// Create New Element
const newEl = document.createElement("span");
newEl.className = "cm-bg"; // *** See comment on question
const newEl2 = document.createElement("span");
newEl2.className = "cm-base"; // *** See comment on question
// Insert New Element AFTER an Element
el.parentElement.insertBefore(newEl, el);
el.parentElement.insertBefore(newEl2, el);
}