Assume I have 2 groups of divs -- both with click buttons, which when clicked, it will change the text content of the child within that group.
How can I accomplish that with pure javascript?
Thanks in advance
HTML
<div class="parent">
<button>Click</button>
<div class="child">Test1</div>
<div class="child">Test4</div>
</div>
<div class="parent">
<button>Click</button>
<div class="child">Test2</div>
<div class="child">Test5</div>
</div>
Javascript
var button = document.querySelectorAll("button");
for(i = 0; i < button.length; i++){
button[i].addEventListener("click", function(){
var parent = document.querySelectorAll(".parent");
var child = parent.querySelector(".child:nth-child(2)");
this.child.textContent = "success"; //just made up to show what I'm trying to accomplish
});
}
Assuming that you want to change only the first div element inside parent, here's one approach:
var button = document.getElementsByTagName("button");
Array.from(button).forEach(v => v.addEventListener('click', function() {
this.parentNode.children[1].innerHTML = 'success';
}));
<div class="parent">
<button>Click</button>
<div class="child">Test1</div>
<div class="child">Test4</div>
</div>
<div class="parent">
<button>Click</button>
<div class="child">Test2</div>
<div class="child">Test5</div>
</div>
Simply use the this keyword to figure out which button is clicked, then get its .parentNode and afterwards its .children, select the second one ([1]) and change the text, like so:
var button = document.querySelectorAll("button");
for(i=0; i < button.length; i++) {
button[i].addEventListener("click", function() {
this.parentNode.children[1].innerHTML = 'success';
});
}
<div class="parent">
<button>Click</button>
<div class="child">Test1</div>
<div class="child">Test4</div>
</div>
<div class="parent">
<button>Click</button>
<div class="child">Test2</div>
<div class="child">Test5</div>
</div>
Related
I just create multiple div and append in java script but I also need to give unique id to all append child so later I can change color of any div.
my view
<div class="main" style=" background-color: white">
<div class="first">
<div class="box"></div>
<div class="box1"></div>
</div>
<div class="2nd">
<div class="box2"></div>
<div class="box3"></div>
</div>
<div class="third">
<div class="box4"></div>
<div class="box5"></div>
</div>
</div>
<script>
for(var i = 0; i< 5; i++)
$(".first").append("<div class='box'></div><div class='box1'></div>");
for(var i = 0; i< 5; i++)
$(".2nd").append("<div class='box2'></div><div class='box3'></div>");
for(var i = 0; i< 5; i++)
$(".third").append("<div class='box4'></div><div class='box5'></div>");
</script>
Or is there any better method to achieve that?
You can use HTML DOM command .querySelectorAll() to return a list of children that match a given attribute. For example if you give your parent div an ID: id="mainDiv", and all the children divs the same class: class="childDiv", you can then do the following:
var mainDiv = document.getElementById("mainDiv");
var childrenDivs = mainDiv.querySelectorAll(".childDiv");
// childrenDivs is now a list containing all of your sections which you can reference using an index
// Eg...
childrenDivs[0].append();
i have this html collection, i want if i click on any div class ".sday"
any other div that are present after that be remove .
for example if we click on sday 2 we should keep sday1 and sday 2, and 3 and 4 must delete
my script removing count is ok but it delete wrong div.
any idea?
<div id="parent" class="parent">
<div class="room-sheet">
<div class="sday">1</div>
</div>
<div class="room-sheet">
<div class="sday">2</div>
</div>
<div class="room-sheet">
<div class="sday">3</div>
</div>
<div class="room-sheet">
<div class="sday">4</div>
</div>
</div>
script(using jquery)
<script>
$(".sday").click(function(){
console.log("hello");
var parentElement = $(this).parent().parent().find('.room-sheet');
var parentChildernCount = $(this).parent().parent().find('.room-sheet').length;
var elementIndex = $(this).closest('.room-sheet').index();
var dd = parentChildernCount - elementIndex;
for(let i=elementIndex; i < dd; i++){
//note: make sure any element after our index in deleted!!!
$("#parent").find('.room-sheet').children().eq(i).remove();
}
})
</script>
Listen for clicks on a .sday on the parent, navigate to the parent of the clicked .sday (a .room-sheet), call nextAll to get all subsequent siblings, and .remove() them:
$('#parent').on('click', '.sday', function() {
$(this).parent().nextAll().remove();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="parent" class="parent">
<div class="room-sheet">
<div class="sday">1</div>
</div>
<div class="room-sheet">
<div class="sday">2</div>
</div>
<div class="room-sheet">
<div class="sday">3</div>
</div>
<div class="room-sheet">
<div class="sday">4</div>
</div>
</div>
Also, there's no need to require a big library like jQuery for something this simple, you may implement this with native DOM methods, if you like:
document.querySelector('#parent').addEventListener('click', ({ target }) => {
if (!target.matches('.sday')) {
return;
}
const sheet = target.parentElement;
while (sheet.nextSibling) {
sheet.nextSibling.remove();
}
});
<div id="parent" class="parent">
<div class="room-sheet">
<div class="sday">1</div>
</div>
<div class="room-sheet">
<div class="sday">2</div>
</div>
<div class="room-sheet">
<div class="sday">3</div>
</div>
<div class="room-sheet">
<div class="sday">4</div>
</div>
</div>
Save the current number and the maximum number in variables then just iterate through them, making sure not to delete the clicked one:
$(".sday").on("click", function() {
let start = parseInt($(this).text());
let finish = parseInt($(".sday").last().text());
for (let i = start + 1; i <= finish; i++) {
$(`.sday:conatins(${i})`).remove();
}
});
I want to traverse through pages and toggle active class through them. How should I do this without using set class?
HTML
<div class="page active"></div>
<div class="set">
<div class="page"></div>
<div class="page"></div>
</div>
<div class="page"></div>
jQuery
$('.active').toggleClass('active').toggle().nextAll('.page').toggleClass('active');
I am assuming that by "traverse" you mean you want to toggle the .page divs one by one in a certain order.
If that is the case, write an algorithm that traverses a tree: given a root, toggle if it is a .page, and recursively deal with each of its children
function traverse(root){
if(!root) return;
if(root.hasClass('page')) root.toggle('active');
root.children().forEach(function(child){
traverse(child);
});
//lets say you want to bind to click event on every div
$('div').click(function(){
traverse($(this));
});
}
Unfortunately we don't have a direct way to find the next non sibling element, but we can handle that situation in many ways using jquery functions. I just tried on way to achieve your goal, check out this working fiddle and let me know if you need any clarity, added some inline comments also for your understanding.
HTML:
<div class="page active">div 1</div>
<div class="page">div 2</div>
<div class="set">
<div class="page">set 1 - div 1</div>
<div class="page">set 1 - div 2</div>
<div class="page">set 1 - div 3</div>
</div>
<div class="page">div 5</div>
<div class="set">
<div class="page">set 2 - div 1</div>
<div class="page">set 2 - div 2</div>
</div>
<div class="page">div 6</div>
<button class="next-btn">Next</button>
CSS:
.active {
color: red;
}
.next-btn {
cursor: pointer;
}
Javascript:
$(function() {
$('button').click(function() {
var elem = $(".page.active").toggleClass('active'); // current active element
var nextElem = elem.next(); // next element
// go above one level and get next element
// if no next element exists, means end of the child level
if (!nextElem.length) {
nextElem = elem.parent().next();
}
// if next element has some PAGE children then update the first child element
if (nextElem.children('.page').length > 0 ) {
nextElem.children('.page:first-child').toggleClass('active');
} else if (nextElem.hasClass('page')) {
nextElem.toggleClass('active');
}
});
});
This approach handles the scenario with one child level, you can extend this to multiple levels also with recursive functions, I think this helps you to handle your scenario accordingly.
Working fiddle
You could achieve that using indexes to get the next element in the DOM using the index of active one +1 then active it, I think the following is what you are looking for:
var getActiveIndex = function(){
var active_index;
$('.page').each(function(i){
if ( $(this).hasClass('active') )
active_index = i;
})
return active_index;
}
$('body').on('click', '.next', function(){
var active_page_index = getActiveIndex(); //Get active page index
var new_index = active_page_index+1; //Set the next page index
var next_page = $('.page:eq('+new_index+')'); //Get the next page
$('.page').removeClass('active');
if(next_page.length)
next_page.addClass('active');
else
$('.page:first').addClass('active');
})
I hope this helps.
var getActiveIndex = function(){
var active_index;
$('.page').each(function(i){
if ( $(this).hasClass('active') )
active_index = i;
})
return active_index;
}
$('body').on('click', '.next', function(){
var active_page_index=getActiveIndex();
var new_index = active_page_index+1;
var next_page = $('.page:eq('+new_index+')');
$('.page').removeClass('active');
if(next_page.length)
next_page.addClass('active');
else
$('.page:first').addClass('active');
})
.active{
background-color: red;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="page active">page</div>
<div class="set">
<div class="page">- Set page</div>
<div class="page">- Set page</div>
</div>
<div class="page">page</div>
<div class="page">page</div>
<div class="page">page</div>
<div class="set">
<div class="page">- Set page</div>
<div class="page">- Set page</div>
</div>
<div class="page">page</div>
<br>
<button class='next'>Active the next page</button>
<div class="row">
<div class="parent">
<div class="child">child1</div>
<div class="child">child2</div>
<div class="child">child3</div>
</div>
<div class="parent">
<div class="child">child4</div>
<div class="child">child5</div>
<div class="child">child6</div>
</div>
<div class="parent">
<div class="child">child7</div>
<div class="child">child8</div>
<div class="child">child9</div>
</div>
<div class="parent">
<div class="child">child10</div>
<div class="child">child11</div>
<div class="child">child12</div>
</div>
<div class="parent">
<div class="child">child13</div>
<div class="child">child14</div>
<div class="child">child15</div>
</div>
<div class="parent">
<div class="child">child16</div>
<div class="child">child17</div>
<div class="child">child18</div>
</div>
</div>
I have sortable divs and i want to save the order of divs. But if i use jquery each function it loops parent divs and passing another parent after taking all childs of it vertically.What i am trying to do is getting child1,child4,child7,child10.. and so on. If we think this as a table i want to take values of cell row by row but jquery each doing this column by column.
The output that i want is 1,4,7,10,13,16,2,5,8,11,14,17,3,6,9,12,15,18
here is code in fiddle
Please check demo
var arr=[];
var count = $(".parent")[0].children.length;
for (var i = 0 ; i < count ; i++){
$(".parent").each(function(){
arr.push($(this.children[i]).text())
});
}
console.log(arr)
Please check this code made for you and let me know, If it's working for you or not.
var cnt = 0;
$(".parent:first-child .child").each(function () { cnt++; });
for (var i = 1; i <= cnt; i++) {
$(".parent").each(function () {
console.log($(this).children('.child:nth-child(' + i + ')').html());
});
}
I have a layout like this and I need to reach the AreaForMapsn nodes and hide them
This is my HTML:
<div id="layout1" class="layout1_wrapper">
<div class="grid">
<div class="block">
<div id="AreaForMaps1" name="AreaForMaps1">
<div id="googlemaps1">
</div>
</div>
</div>
</div>
<div class="grid">
<div class="block">
<div id="AreaForMaps2" name="AreaForMaps2">
<div id="googlemaps2">
</div>
</div>
</div>
</div>
<div class="grid">
<div class="block">
<div id="AreaForMaps3" name="AreaForMaps3">
<div id="googlemaps3">
</div>
</div>
</div>
</div>
</div>
JavaScript:
<script>
document.getElementById("Button").onclick = function(){
//need to reach all AreaForMapsXXX divs and hide them
var myDiv = document.getElementById( "layout1" );
var children = document.getElementById(layout1).childNodes;
for(i=0; i<children.length; i+=3) {
document.getElementById(children[i].id).style.display = "none";
}
}
</script>
One possible way is to add a class, say "AreaForMaps", to all of them and then simply use document.getElementsByClassName (or jQuery or whatever you're using).
There are several ways to go about it. Here's one way.
document.getElementById("Button").onclick = function(){
var myDiv = document.getElementById( "layout1" );
var divs = myDiv.getElementsByTagName("div");
for(i=0; i<divs.length; i++) {
if (divs[i].id.indexOf("AreaForMaps") === 0)
divs[i].style.display = "none";
}
}
Your code was only targeting nodes that are immediate children of "layout1", and was including text nodes (the tab and newline characters are represented as nodes in the DOM).
This code gets all div elements that descend from "layout1", and verifies that the first part of their ID starts with "AreaForMaps" before hiding it.
If the list of browsers you support only include IE8 and higher, you can do this instead:
document.getElementById("Button").onclick = function(){
var divs = document.querySelectorAll( "#layout1 div[id^=AreaForMaps]" );
for(i=0; i<divs.length; i++)
divs[i].style.display = "none";
}