Elements Removal in javascript [duplicate] - javascript

This question already has answers here:
removeChild() method is breaking for loop
(4 answers)
JavaScript DOM remove element
(4 answers)
Closed 2 years ago.
i want to remove specific child elements from my div element using javascript but i can't able to do that.
this is the format of element
<div class="div1">
<span class="spanp">span1<span class="spanc">spanchild1</span></span>
<span class="spanc">spanc</span>
<span class="spanp">span2<span class="spanc">spanchild2</span></span>
<span class="spanc">spanc</span>
<span class="spanp">span3<span class="spanc">spanchild3</span></span>
<span class="spanc">spanc</span>
</div>
i want to delete span elements of class="spanc" only.
how i can do it using javascript only
var list=document.getElementsByClassName("spanc");
for(var i=0;i<list.length;i++){
list[i].parentNode.removeChild(list[i]);
}
when i run this i'am able to delete only main spanc class elements and subelements of class spanp elements on odd indexs only.even index spanp class subelements are strill in list

I suppose this could do the trick:
const spanc = document.querySelectorAll('.div1 .spanc');
spanc.forEach(node => node.remove());

So part of the issue is the spans you are trying to remove have different parent elements; sometimes it's a span otherwise it's a div.
const itemsToRemove = document.getElementsByClassName('spanc');
const parents = document.getElementsByClassName('spanp');
[...parents].forEach(span => {
const itemsToRemove = span.getElementsByClassName('spanc');
[...itemsToRemove].forEach(item => span.removeChild(item));
});
const outerParent = document.getElementsByClassName('div1')[0];
const upperItemsToRemove = outerParent.getElementsByClassName('spanc');
[...upperItemsToRemove].forEach(item => outerParent.removeChild(item));
<div class="div1">
<span class="spanp">span1<span class="spanc">spanchild1</span></span>
<span class="spanc">spanc</span>
<span class="spanp">span2<span class="spanc">spanchild1</span></span>
<span class="spanc">spanc</span>
<span class="spanp">span2<span class="spanc">spanchild1</span></span>
<span class="spanc">spanc</span>
</div>

Thank you for the help i got the answer by using while loop instead of forloop
while(list.length>0){
let i=0;
list[i].parentNode.removeChild(list[i]);
}

Related

sort div's through sort(); [duplicate]

This question already has answers here:
Easiest way to sort DOM nodes?
(9 answers)
Closed last month.
I have list and this list must be sort to a => b throught like btn (example click SORT and we have list to a -> b)
<div class = "list">
<div id = "products"> Sugar </div>
<div id = "products"> Banana </div>
<div id = "products"> Apple </div>
</div>
sorted to for button =>
<div class = "list">
<div id = "products"> Apple </div>
<div id = "products"> Banana </div>
<div id = "products"> Sugar </div>
</div>
Idk how did that with like btn :(
I tried something like that =>
// For the HTML //
<button class = 'sortBtn' onclick = 'sort()'>Sort</button>
<script>
const sort = document.quertSelector('.sortBtn');
sort.addEventListenet('click', function sort(a, b){
$parent.sort();
})
</script>
I would be grateful for help :) <3
There's a few issues in your code.
Typo: quertSelector -> querySelector
Typo: addEventListenet -> addEventListener
The repeated id in your HTML are invalid, convert them to class instead.
The function you provide to addEventListener should be anonymous in this case. Giving it a name here serves no purpose other than to waste bytes.
Avoid using inline event handlers, such as onclick, in your HTML code. It's outdated and no longer good practice. Use unobtrusive event handlers instead, such as addEventListener(), which you already use elsewhere in your code.
sort() should compare the a and b arguments and return an integer depending on which way to sort them. In this case, as you're comparing strings you can use localeCompare() on the textContent property of the elements.
After the sort() has completed you need to update the DOM to respect the new order of the elements. To do this you can call append() on the parent element, supplying the children as the argument.
Here's a working example with these issues addressed:
const sortButton = document.querySelector('.sortBtn');
const list = document.querySelector('.list');
const products = list.querySelectorAll('.products');
sortButton.addEventListener('click', () => {
const sortedElements = Array.from(products).sort((a, b) => a.textContent.localeCompare(b.textContent));
list.append(...sortedElements);
})
<div class="list">
<div class="products">Sugar</div>
<div class="products">Banana</div>
<div class="products">Apple</div>
</div>
<button type="button" class="sortBtn">Sort</button>
Convert the children of the parent element to an array. Then you can use the array sort() method to sort it, then append the children back to the parent in that order.
document.querySelector(".sortBtn").addEventListener("click", () => sortDiv(document.querySelector(".list")));
function sortDiv(parent) {
let children = [...parent.children];
children.sort((a, b) => a.innerText.localeCompare(b.innerText));
parent.innerHTML = '';
children.forEach(child => parent.appendChild(child));
}
<div class="list">
<div class="products"> Sugar </div>
<div class="products"> Banana </div>
<div class="products"> Apple </div>
</div>
<button class='sortBtn'>Sort</button>

How to find out which parent contains an attribute? [duplicate]

This question already has answers here:
What is the pure JavaScript equivalent of jQuery's .parents() method? [duplicate]
(2 answers)
Closed 7 months ago.
A question:
How to find out which parent contains an attribute?
Example:
<div custom-attribute>
<div>
<div>
<div>
<div><p>some text</p></div>
</div>
</div>
</div>
</div>
I can't know exactly where this attribute will be applied and on which element.
I need to iterate through all the parents from the <p> element.
Without jquery
Use a while loop to iterate the parents until you find the parent that has the attribute:
const elem = document.getElementById('elem');
let parent = elem.parentElement;
while (parent && !parent.hasAttribute('custom-attribute')) {
parent = parent.parentElement;
}
if (parent) {
console.log(parent);
}
<div custom-attribute>
<div>
<div>
<div>
<div>
<p id="elem">some text</p>
</div>
</div>
</div>
</div>
</div>
const elem = document.querySelector('#elem');
const list = Array.from(document.querySelectorAll('[custom-attribute]'));
const parent = list.find(item => item.contains(elem));
// ...
If you may have not only one parent that has the custom-attribute, you'd better loop as you mentioned in question.

How to add divs to multiple instances of a class?

I have been using some code to add divs to my buttons for styling using the code below, it works fine on the first instance of the button but it does not add the divs to any buttons after that? what am I missing? I'm willing to learn and have tried to Google this but I'm getting buried deep in things I don't fully understand just yet. Would be great if any answer could be in plain Javascript and not jQuery.
JS
// Parent Element
const el = document.querySelector(".myclass");
// Create New Element
const newEl = document.createElement("span");
newEl.classList= "cm-bg";
const newEl2 = document.createElement("span");
newEl2.classList= "cm-base";
// Insert New Element BEFORE an Element
el.before(newEl);
el.before(newEl2);
HTML
<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>
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);
}

Get concatenated text of elements using JavaScript

I tried it with getElementById and it worked. But now I want the same with multiple div's so I have to use classes. So I changed the method to getElementsByClassName and now it says undefined.
(The function is called when a option in a select changes. This works correctly)
HTML:
<div class="item_content">
<h3 class="filmnaam">22 jump street</h3>
</div>
<div class="item_content">
<h3 class="filmnaam">rio 2</h3>
</div>
Javascript:
function sorting(sortingway) {
alert(sortingway.value);
var titelfilms = document.getElementsByClassName("filmnaam");
var titels = titelfilms.innerHTML;
console.log(titels[0]);
}
Is there a way to do this without jQuery?
getElementsByClassName returns a collection, so loop that!
var titelfilms = document.getElementsByClassName("filmnaam");
for (var i = 0; i < titelfilms.length; i++) {
var titels = titelfilms[i].innerHTML;
console.log(titels);
}
titelfilms is a node list, you can't get the innerHTML of a node list as a whole, it contains multiple references to elements which each have their own individual property.
You could loop through and concatenate each innerHTML onto a variable, or you could map() the innerHTML of your returned elements to an array and then join() them up:
function sorting(sortingway) {
var titelfilms = document.getElementsByClassName("filmnaam");
var titels = Array.prototype.map.call(titelfilms, function (el) {
return el.innerHTML;
}).join(' ');
console.log(titels);
}
sorting();
<div class="item_content">
<h3 class="filmnaam">22 jump street</h3>
</div>
<div class="item_content">
<h3 class="filmnaam">rio 2</h3>
</div>

Hide and show spans with a specific class

I'm i'm trying to display songs made by an artist when i click the artist's name.
Here's my HTML
<div id="artists">
<span class="artist" id="Eminem" onclick="showSongs("Eminem")">Eminem</span>
</div>
<div id="songs">
<span style="display:none;" class="Eminem" id="Eminem - Survival" onclick="playSong('Eminem - Survival');">Survival</span>
</div>
And here is my Javascript
function showSongs(artist) {
document.getElementsByClassName(artist).styles.display="inline";
}
This is not all my code, I have more artists and more songs.
but the point is that i want the songs from an artist to display when i click the artists name
I have googled it for a while now, All i found was that i had to display span tags as inline.
If you need more information just ask and i'll edit the post
First, adjust the artist name you are sending to use single quotes, you are breaking the string by using double quotes.
<span class="artist" id="Eminem" onclick="showSongs('Eminem')">Eminem</span>
Then when you get elements by class name you are retrieving a collection and need to loop through them. Shown below:
function showSongs(artist) {
var elements = document.getElementsByClassName(artist);
for(var i = 0; i < elements.length; i++) {
elements[i].style.display="inline";
}
}
Here is a jsFiddle.
EDIT: Ah yes, see the other answers for the other half of the problem.
This code should work, the only thing I see wrong with it is this line:
<span class="artist" id="Eminem" onclick="showSongs("Eminem")">Eminem</span>
You should use single quotes inside the showSongs call:
<span class="artist" id="Eminem" onclick="showSongs('Eminem')">Eminem</span>
If that does not solve the problem, it is probably caused by some other code on the page.
getElementsByClassName returns an array-like collection. I don't think you can change the style this way.. Maybe you could try this :
function showSongs(artist) {
var artists = document.getElementsByClassName(artist);
for(var i = 0; i < artists.length; i++) {
artists[i].style.display="inline";
}
}
Would be a lot easier with jquery.
Here you go: http://jsfiddle.net/LVRGZ/3/
<div id="artists">
<span class="artist" onclick="showSongs('Eminem')">Eminem</span>
</div>
<div id="Eminem" style="display:none;">
<span id="Eminem - Survival" onclick="playSong('Eminem - Survival');">Survival</span><br/>
<span id="Another Song" onclick="playSong('Eminem - 2');">Another Song</span><br/>
<span id="A Third Song" onclick="playSong('Eminem - 3');">A Third Song</span><br/>
</div>
<script>
showSongs=function(id) {
alert("Showing "+id);
document.getElementById(id).style.display='';
}
</script>

Categories

Resources