Count parent child child nodes - javascript

So I want to know how do I get count of parent child child childs for example:
const parent = document.querySelectorAll('.parent');
parent.forEach(el => {
const ul = el.querySelector('.child3-child');
const div = document.createElement('div');
div.textContent = ul.childNodes.length;
el.append(div);
});
<div class="parent">
<div class="child1">
text
</div>
<div class="child2">
text
</div>
<div class="child3">
<ul class="child3-child">
<li>
some text...
</li>
<ul>
</div>
</div>
And now I want count how many <ul class="child3-child"> has child elements in this case it has only 1 li.

Use children instead of childNodes. The former includes HTML Elements while the latter includes text nodes.
Close your </ul> tag properly or else the borwser will think it's opening a nested element.
const parent = document.querySelectorAll('.parent');
parent.forEach(el => {
const ul = el.querySelector('.child3-child');
const div = document.createElement('div');
div.textContent = ul.children.length;
el.append(div);
});
<div class="parent">
<div class="child1">
text
</div>
<div class="child2">
text
</div>
<div class="child3">
<ul class="child3-child">
<li>
some text...
</li>
</ul> <!--- This wasn't properly closed -->
</div>
</div>

Related

Displaying a random div by appendChild?

In the Index file I have these divs which I note by IDs, let's say there are 3 of these:
<div class="col-sm-6 col-md-4 col-lg-3 grid-item" id="one">
<div class="well">
<a href="http://" target="_blank">
<img class="class" src="img/pic.jpg" alt=""/>
</a>
<p></p>
<nav>
<div class="anim-icons">
<ul>
<li>
<a href="#">
<img src="" alt="">
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
And this is part of the JS file:
var one = document.querySelector("#one");
var two = document.querySelector("#two");
var three= document.querySelector("#three");
const randomButton= document.querySelector("#randomButton");
function Randomizer() {
var array = [one, two, three];
var result = array[Math.floor(Math.random() * array.length)];
console.log(result);
var node = document.createElement("DIV");
node.innerHTML(result);
node.appendChild(result);
document.getElementById("#placeofresult").appendChild(node);
}
randomButton.addEventListener("click", Randomizer, false);
This if where I want that above div to be displayed:
<div>
<button class="btn btn-light" id="randomButton">
press!
</button>
<br>
<div id="placeofresult"> </div>
</div>
If I press the button, I want one of the divs from the Index file displayed in the div on the page where this JS belongs, but I don't know how to append a whole div by an id.
Thank you for your insights in advance!
appendChild will work fine if you need to insert div into another one.
Suppose, there is <div id="one">One</div> which you want to append inside <div id="placeofresult"></div>; you need to do the following
document.getElementById("placeofresult").appendChild(document.getElementById("one"));
or if you want to clone the div with id="one" and insert it, do the following:
const newOne = document.getElementById("one").cloneNode(true);
document.getElementById("placeofresult").appendChild(newOne);
Hope it helps. Revert for any doubts.
A solution for your problem could be to write the three divs you want to display entirely into js like this:
const divs = [
"
<div id="one">
...
</div>
",
"<div id="two">
...
</div>
",
"<div id="three">
...
</div>
"
]
Using your randomButton
randomButton.addEventListener("click", Randomizer, false);
You just have to set the innerHTML of your result div to the corresponding div of the divs array:
function Randomizer() {
var resultHTML = divs[Math.floor(Math.random() * array.length)];
document.getElementById("#placeofresult").innerHTML(resultHTML);
}
Another solution is to set the style of your divs to display none and display only the randomly chosen div after the button click:
Your html:
<div id="placeofresult">
<div id="one" style="display:none">
...
</div>
<div id="two" style="display:none">
...
</div>
<div id="three" style="display:none">
...
</div>
</div>
Your Randomizer:
function Randomizer() {
var array = [one, two, three];
// Set all divs to hidden
array.forEach(function(id){
document.getElementById(id).style.display = "none";
})
var result = array[Math.floor(Math.random() * array.length)];
document.getElementById(result).style.display = "block";
}

How to get the rowIndex of a div element clicked

I want to get the rowIndex of the <div> I clicked.
<div id="parent" onClick="this.click()">
<div id="1">
<span text="22"></span>
</div>
<div id="2"><span text="32"></span></div>
<div id="3"><span text="232"></span></div>
<div id="4"><span text="242"></span></div>
<div id="5"><span text="252"></span></div>
</div>
I'm at a stage where I get the <div> I have clicked, lets say I have:
<div id="3"><span text="232"></div>
How can I get the id and the value of the text in the <span> inside that <div>?
Add an event handler to the container (#parent) using Element.addEventListener(). When the handler is triggered, check if the event target is a span Element.matches().
If it is, get the id from the parent node (the div), and the text attribute from the span, using Element.getAttribute():
var container = document.getElementById('parent');
container.addEventListener('click', function(e) {
if (!e.target.matches('#parent > div > span')) return;
var id = e.target.parentNode.id;
var text = e.target.getAttribute('text');
console.log(id, text);
});
<div id="parent">
<div id="1">
<span text="22">1</span>
</div>
<div id="2"><span text="32">2</span></div>
<div id="3"><span text="232">3</span></div>
<div id="4"><span text="242">4</span></div>
<div id="5"><span text="252">5</span></div>
</div>
If you are using Jquery, this will work [Tested]:
$("#parent").find('span').each(function(){
$(this).on('click', function(){
console.log($(this).parent().attr('id'));
});
});
Let me know if any issues with this

Using querySelectorAll to target nested elements

How do I use querySelectorAll to select <p> with parent <div class="entry-content"> only?
Eg.
<div>
<p>ParagraphA</p>
<p>ParagraphB</p>
</div>
<div class="entry-content">
<p>Paragraph1</p>
<p>Paragraph2</p>
<p>Paragraph3</p>
</div>
<p>Paragraph4</p>
<p>Paragraph5</p>
I only want Paragraph1 ~ Paragraph3 to be selected.
I'm currently using var x = document.querySelectorAll("p"); which is selecting everything.
var x = document.querySelectorAll("div > p"); is very closed to getting what I need, but I need to ensure only selecting all <p> elements within the <div class="entry-content"> with class specified.
How can this be modified to accomplish the task?
Specify the div's class:
document.querySelectorAll('div.entry-content > p');
var entryContent = document.querySelector('.entry-content');//matches first
var p = entryContent.querySelectorAll("p"); //matches all
console.log(p);
<div>
<p>ParagraphA</p>
<p>ParagraphB</p>
</div>
<div class="entry-content">
<p>Paragraph1</p>
<p>Paragraph2</p>
<p>Paragraph3</p>
</div>
<div>
<p>Paragraph4</p>
<p>Paragraph5</p>
</div>

create list of each siblings children

I have multiple sections with multiple sub-sections. Each section should have a list of all sub-section h3-headings within this section. Given this HTML:
<div class="allwrap">
<div class="main-section" id="m1">
<h2>Main-1-Headline</h2>
<ul class="sub-sections-list">
<!-- generate LIs of each [#main-1 > .sub-section h3 text] -->
</ul>
<div class="sub-section" id="m1-s1">
<h3>Main-1-Sub-1-Headline</h3>
</div>
<div class="sub-section" id="m1-s2">
<h3>Main-1-Sub-2-Headline</h3>
</div>
</div>
<div class="main-section" id="main-2">
<h2>Main-2-Headline</h2>
<ul class="sub-sections-list">
<!-- generate LIs of each [#main-2 > .sub-section h3 text] -->
</ul>
<div class="sub-section" id="m2-s1">
<h3>Main-2-Sub-1-Headline</h3>
</div>
<div class="sub-section" id="m2-s2">
<h3>Main-2-Sub-2-Headline</h3>
</div>
</div>
</div>
So I iterate over each sections subsection H3 and have an array of ALL h3-headings now which is not what i want to accomplish:
var myList = [];
$('.main-section .sub-section').each(function(){
myList.push($(this).find('h3').text());
});
$.each(myList, function(){
var li = $('<li/>').appendTo('.sub-sections-list');
$('<a/>').attr('href', '#').text(this).appendTo(li);
});
How can i make it so that not all h3-headings of all sections are in the list but only the headings of the respective parent section? The result should look like this:
Main-1-Headline (begin of Main-section-1)
Main-1-Sub-1-Headline
Main-1-Sub-2-Headline
Main-1-Sub-1-Headline (begin of sub-section-1)
Some content here (not in above HTML for keeping it simple)
Main-1-Sub-2-Headline (begin of sub-section-2)
Some content here (not in above HTML for keeping it simple)
Main-2-Headline (begin of Main-section-2)
Main-2-Sub-1-Headline
Main-2-Sub-2-Headline
Main-2-Sub-1-Headline (begin of sub-section-1)
Some content here (not in above HTML for keeping it simple)
Main-2-Sub-2-Headline (begin of sub-section-2)
Some content here (not in above HTML for keeping it simple)
I think you want this.
Updated short way demo
$('.main-section h3').each(function(){
$(this).parent().prevAll(".sub-sections-list").append('<li>'+$(this).text()+'</li>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="allwrap">
<div class="main-section" id="m1">
<h2>Main-1-Headline</h2>
<ul class="sub-sections-list">
<!-- generate LIs of each [#main-1 > .sub-section h3 text] -->
</ul>
<div class="sub-section" id="m1-s1">
<h3>Main-1-Sub-1-Headline</h3>
</div>
<div class="sub-section" id="m1-s2">
<h3>Main-1-Sub-2-Headline</h3>
</div>
</div>
<div class="main-section" id="main-2">
<h2>Main-2-Headline</h2>
<ul class="sub-sections-list">
<!-- generate LIs of each [#main-2 > .sub-section h3 text] -->
</ul>
<div class="sub-section" id="m2-s1">
<h3>Main-2-Sub-1-Headline</h3>
</div>
<div class="sub-section" id="m2-s2">
<h3>Main-2-Sub-2-Headline</h3>
</div>
</div>
</div>
Old way
$('.main-section').each(function() {
var myList = [];
$(this).find("h3").each(function() {
myList.push($(this).text());
});
$subSectionList = $(this).find('.sub-sections-list');
$.each(myList, function() {
var li = $('<li/>').appendTo($subSectionList);
$('<a/>').attr('href', '#').text(this).appendTo(li);
});
});
Something like this (optimized version):
$('.main-section').each(function(){
var ul = $(this).find('.sub-sections-list');
$(this).find('h3').each(function(){
ul.append('<li>'+$(this).text()+'</li>');
});
});
Example: https://jsbin.com/gefupivoji/edit?html,js,output

Find Child elements in a div and append them to another Child element using javascript

I want the elements to be appended to another elements - they have to
be found in a div class that have id="parent".
the code must be only in clean javascript. The problem is, why i cant use just append - children append only for 1 element(first block) so need a loop that will get every element(2) to append to the (1) element.
<!-- FirstBlock -->
<div id="parent">
<div id="firstElement">
</div>
<div id="secondElement">
</div>
</div>
I want it to look like this
<!-- FirstBlock -->
<div id="parent">
<div id="firstElement">
<div id="secondElement">
</div>
</div>
</div>
Here is the code i tried:
function getElement() {
var firstElement = document.getElementById('firstElement');
var secondElement = document.getElementById('secondElement');
var parent = document.getgetElementById('parent').children;
for(var i = 0; i < parent.length; i++){
for(firstElement in parent[i]){
if(!(secondElement in firstElement){
firstElement.appendChild(secondElement);
});
};
};
Fiddle
With the ID's being the same, you need to use a class attribute instead or change the ID for each of those elements. Here's an example of how you could achieve your result(CSS for visual example).
function getElement() {
var parents = document.getElementsByClassName('parent'),
parentsLength = parents.length;
while (parentsLength--){
var firstElements = parents[parentsLength].getElementsByClassName('firstElement'),
firstElementsLength = firstElements.length,
secondElements = parents[parentsLength].getElementsByClassName('secondElement');
while(firstElementsLength--) {
var secondElementsLength = secondElements.length;
while(secondElementsLength--) {
firstElements[firstElementsLength].appendChild(secondElements[secondElementsLength]);
}
}
};
}
getElement();
.firstElement {
height: 50px;
border: 1px solid #000;
}
.secondElement {
background-color: #aaa;
}
<!-- FirstBlock -->
<div class="parent">
<div class="firstElement">
dddd
</div>
<div class="secondElement">
aaa
</div>
</div>
<!-- SecondBlock -->
<div class="parent">
<div class="firstElement">
firstElement
</div>
<div class="secondElement">
secondElement
</div>
</div>
<!-- ThirdBlock -->
<div class="parent">
<div class="firstElement">
firstElement
</div>
<div class="secondElement">
secondElement
</div>
</div>
I want it look like this
<!-- FirstBlock -->
<div class="parent">
<div class="firstElement">
firstElement
<div class="secondElement">
secondElement
</div>
</div>
</div>
<!-- SecondBlock -->
<div class="parent">
<div class="firstElement">
firstElement
<div class="secondElement">
secondElement
</div>
</div>
</div>
<!-- ThirdBlock -->
<div>
<div class="parent">
<div class="firstElement">
firstElement
<div class="secondElement">
secondElement
</div>
</div>
</div>
A quick rundown of the JavaScript..
We're getting each element with the parent class and setting a variable to the length of that object.
The while loop is running through each of those divs and getting the divs inside that contain the firstElement and secondElement classes.
Then more loops take each element with the class secondElement and insert them into the elements with the class firstElement.
At the end of it, for every parent div, any divs with a class of secondElement will be inserted into every div with a class of firstElement inside of that parent div.
Here is the fiddle that I went off of for modifications. Hope this helps!
Change your HTML code to have classes, instead of id's. There can't be more than one element with the same id.
<div class="parent">
<div class="firstElement">
</div>
<div class="secondElement">
</div>
</div>
Then use the following JavaScript:
var parents = document.getElementsByClassName("parent");
for(i = 0; i < parents.length; i++){
var current = parents[i];
var firstElement = current.getElementsByClassName("firstElement")[0];
var secondElement = current.getElementsByClassName("secondElement")[0];
firstElement.appendChild(secondElement);
current.removeChild(firstElement);
}

Categories