Click on parent to open it's child inside collection(vanilla JS) - javascript

I am new to javascript, which is why I hope I could get an advise of how to make the following using vanilla JS.
I have structure
<div class="parent">
<div class="child">Some content</div>
</div>
<div class="parent">
<div class="child">Some content</div>
</div>
<div class="parent">
<div class="child">Some content</div>
</div>
<div class="parent">
<div class="child">Some content</div>
</div>
What I want is to be able to click on each parent to open only it's own child. Could someone give an idea how that could be done with vanilla js? I assume this should be done using collections in JS. But I have no idea how to connect each parent and each child with each other. Would be grateful for any advise.

It works like this (see comments in code):
// Iterate over a collection of elements with class 'parent'
for (const parent of document.querySelectorAll('.parent')) {
// to each parent, add a click listener
parent.addEventListener('click', function(clickEvent) {
// check if the element clicked was the parent and not a click bubbling up from a child
if (clickEvent.target === parent) {
// find the child contained
const child = parent.querySelector('.child');
// toggle the visibility using the hidden property
child.hidden = !child.hidden;
}
})
}
.parent::before { content: "parent, click here to toggle child"; }
<div class="parent">
<div class="child" hidden>Some content 1</div>
</div>
<div class="parent">
<div class="child" hidden>Some content 2</div>
</div>
<div class="parent">
<div class="child" hidden>Some content 3</div>
</div>
<div class="parent">
<div class="child" hidden>Some content 4</div>
</div>
Also note that HTML offers an element with this functionality already:
<details>
<div>Some content 1</div>
</details>
<details>
<div>Some content 2</div>
</details>
<details>
<div>Some content 3</div>
</details>
<details>
<div>Some content 4</div>
</details>

first, need to get elements with class "parent"
with a for loop bind addEventListener of onclick function
in function find child div element with class "child "
then show the child element
var elements = document.getElementsByClassName("parent");
var myFunction = function() {
var childNode = this.querySelector('.child');
childNode.style.display = "block";
};
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', myFunction, false);
}
.child{
display:none;
}
<div class="parent">p1
<div class="child">p1 Some content</div>
</div>
<div class="parent">p2
<div class="child">p2 Some content</div>
</div>
<div class="parent">p3
<div class="child">p3 Some content</div>
</div>
<div class="parent">p4
<div class="child">p4 Some content</div>
</div>

Related

Selecting a parent class from a child class when there are multiple div's of same parent class

There are four parent div's with same class and all of them have a child with class 'child'. Now the question is, Let's say I click on the First parent div's Child div(First Child) and I want to have some effect on it's parent i.e 'First Parent' to be effected only. Due to being similar class' all parent div's will be effected.
Here's the HTML
<div class="parent"> //First Parent
<div class="child"></div> //First Child
</div>
<div class="parent">
<div class="child"></div>
</div>
<div class="parent">
<div class="child"></div>
</div>
<div class="parent">
<div class="child"></div>
</div>
Here's the JQuery
$('.child').on('click',function(){
$(this).parent('.parent').css({
'display':'none';
});
});
Clicking on child element will effect all parent div's with class "parent". Either I can give them all separate classes then write onClick() method for all of them but that is not a proper solution.
You can do
$(this).parent().hide();
if you want to hide the parent of the clicked div
Use closest('.class')
$('.child').click(function() {
$(this).closest('.parent').css('display':'none');
});
I Updated my answer !
Your answer is correct and a good practice, I don't see what the issue here is.
The only change you could do $(this).parent('.parent').hide(); instead of using the jQuery css method.
try this code
$(document).ready(function() {
$('.child').click(function() {
$(this).parent().css('display', 'none');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="child">first</div>
</div>
<div class="parent">
<div class="child">second</div>
</div>
<div class="parent">
<div class="child">third</div>
</div>
<div class="parent">
<div class="child">fourth</div>
</div>
$('.child').on('click',function(){
$(this).closest('.parent').css({
'display':'none'
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent"> //First Parent
<div class="child">div 1</div> //First Child
</div>
<div class="parent">
<div class="child">div 2</div>
</div>
<div class="parent">
<div class="child">div 3</div>
</div>
<div class="parent">
<div class="child">div 4</div>
</div>
alterate your JS as follow:
$('.child').on('click',function(){
$(this).parent().css({
'display':'none'
});
});
For me, on click of a div, it hides its parent. Not others.
By the way, you had a ";" after 'none' which is invalid as this is a object, and accepts only either nothing or a comma.
see https://jsfiddle.net/n66sdgdz/
Okay, so lots of answers here with "try this" or other examples.
First off, your code actually works, as you can see here:
Fiddle
However, there was one error in you code. This being the ; at the end of your 'display':'none';
There should be no ; inside a javascript object.
$(document).ready(function() {
$('.child').on('click',function(){
$(this).closest('.parent').css('display','none');
});
});
OR
$('.child').on('click',function(){
$(this).parent('.parent').eq(0).css('display','none');
});
https://jsfiddle.net/t9wxbLs8/

How to use Jquery to access a div element 2 layers down

For the life of me I can't figure out how to access the first div with text "I want this one" starting with the id of div1
My attempt:
$("#div1").first().first().html();
Here is an example
<div id="div1">
<div class="row">
<div class="another">I want this one</div>
<div class="another">Not this one</div>
</div>
</div>
Try this
1.
$("#div1 .another:first").html();
2.
$("#div1 .another").first().html();
3.
$("#div1 .another").eq(0).html();
Example
If you literally want the first element within the first element, you can do it in one selector using pure javascript selectors for performance like so:
var row = $('#div1 > div:first-child > div:first-child');
alert(row.text());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="div1">
<div class="row">
<div class="another">I want this one</div>
<div class="another">Not this one</div>
</div>
<div class="row">
<div class="another">Another one</div>
<div class="another">Yet another one</div>
</div>
</div>

Create a variable that contains the id of clicked div

Does anybody have any idea how to create a variable that contains the id of a clicked div?
I want to hide all the #content-wrappers on page load apart from the first one then when the .square has been clicked for it to display the div with the same class as the id that has been clicked, it doesn't make much sense when you write id down but if you look at my fiddle then it should hopefully make sense?
http://jsfiddle.net/alexjamest/Lkaxza22/
$('#content-wrapper').hide();
$(".square").click(function() {
var id_name= $(this).attr(id);
if $('#content-wrapper').hasClass(id_name){
$(this).fadeIn();
}
});
<div id="content-wrapper" class="c1">Content 1</div>
<div id="content-wrapper" class="c2">Content 2</div>
<div id="content-wrapper" class="c3">Content 3</div>
<div id="content-wrapper" class="c4">Content 4</div>
<div id="content-wrapper" class="c5">Content 5</div>
<div id="content-wrapper" class="c6">Content 6</div>
<div id="content-wrapper" class="c7">Content 7</div>
<div id="content-wrapper" class="c8">Content 8</div>
<div class="square" id="c1"></div>
<div class="square" id="c2"></div>
<div class="square" id="c3"></div>
<div class="square" id="c4"></div>
<div class="square" id="c5"></div>
<div class="square" id="c6"></div>
<div class="square" id="c7"></div>
<div class="square" id="c8"></div>
Change your content-wrappers elements so that they contain classes, not ids, since ids should be unique. You can, however, identify your content with some sort of a prefix, like content-:
<div class="content-wrapper" id="content-c1">Content 1</div>
<div class="content-wrapper" id="content-c2">Content 2</div>
<div class="content-wrapper" id="content-c3">Content 3</div>
<div class="content-wrapper" id="content-c4">Content 4</div>
<div class="content-wrapper" id="content-c5">Content 5</div>
<div class="content-wrapper" id="content-c6">Content 6</div>
<div class="content-wrapper" id="content-c7">Content 7</div>
<div class="content-wrapper" id="content-c8">Content 8</div>
Then the following code will work:
$(document).ready(function()
{
$(".content-wrapper").hide();
$(document).on("click", ".square", function()
{
var id = $(this).attr("id");
$("#content-"+id).fadeIn();
});
});
Note the following part
$(".content-wrapper").hide();
which is important, since we're identifying that we wish to hide all elements which contain the class content-wrapper, not the id content-wrapper.
Working Demo.
There are four problems with your code:
$('#content-wrapper').hide(); will only hide the first element with that ID, because IDs have to be unique. Use a common class instead.
var id_name= $(this).attr(id);. id is an undefined variable. You probably want to pass the string "id" instead, or better, just access the property of the DOM element: this.id.
if $('#content-wrapper').hasClass(id_name){ is a syntax error. The condition has to be put in parhenthesis:
if ($('#content-wrapper').hasClass(id_name)) {
However, that alone won't make the condition work, since again, #content-wrapper will only select the first element. Just select the corresponding element by class:
$('.' + this.id).fadeIn();
You can also add .content-wrapper for more granular filtering:
$('.content-wrapper.' + this.id).fadeIn();
Fixed code:
$('.content-wrapper').hide(); // give that class to all elements instead of the ID
$(".square").click(function() {
$('.' + this.id).fadeIn();
});
DEMO
A JQuery-less solution, still with the fade animation.
On load it gets an array of buttons and an array of content wrappers, then it just uses the order to figure out which box to reveal. Will only work with an equal number of buttons and wrappers. I started the wrappers as invisible in the style sheet, so we only have to reveal them. Also remembers which buttons was clicked last and resets its visibility.
<head>
<style>
.content-wrapper{
opacity:0;
transition:opacity 1s ease;/* only showing the normal one, prefixed may be required for portability*/
}
</style>
<script>
window.addEventListener('load',onload,false);
var wrappers;
var buttons;
var last;
function onload(){
wrappers = document.getElementsByClassName('content-wrapper');
buttons = document.getElementsByClassName('square');
var i = buttons.length;
while(i--) // add listener for each button
buttons[i].addEventListener('click',onclick,false);
}
function onclick(){
if(last)wrappers[last].style.opacity = '0.0'; //hide previous
var i = buttons.indexOf(this);
wrappers[i].style.opacity = '1.0'; //show clicked
last = i;
}
</script>
</head>
<body>
<div class='content-wrapper'></div>
<div class='content-wrapper'></div>
<div class='content-wrapper'></div>
<div class='content-wrapper'></div>
<div class='content-wrapper'></div>
<div class='square'></div>
<div class='square'></div>
<div class='square'></div>
<div class='square'></div>
<div class='square'></div>
</body>

Add attribute to a parent element

I have a javascript variable (ex: myElement), that holds a div with class name myClass like shown below.
<div>
<div class="myClass">
<h1>My Div</h1>
<div id="1">Div one Content</div>
<h2>Headline two</h2>
<div id="2">Div two Content </div>
</div>
<div class="myClass">
<h1>My Div</h1>
<div id="1">Div one Content</div>
<h2>Headline two</h2>
<div id="2">Div two Content </div>
</div>
</div>
I want to add an attribute (ex: data-index) to the div having class 'myClass' through jascsript or jQuery so that it could look like this:
<div>
<div class="myClass" data-index="index1">
<h1>My Div</h1>
<div id="1">Div one Content</div>
<h2>Headline two</h2>
<div id="2">Div two Content </div>
</div>
<div class="myClass" data-index="index2">
<h1>My Div</h1>
<div id="1">Div one Content</div>
<h2>Headline two</h2>
<div id="2">Div two Content </div>
</div>
</div>
How can you achieve this?
Please note: I have this div in a javascript variable called myElement and the following code
myElement.attr('data-index','index')
does not work.
Update:
I could try like First appending the div stored in variable myElement to the DOM, then add the attribute:
$('div.myClass').attr('data-index','index');
but the problem is in the DOM I have like 100s of div with the class myClass.
well, the better way is you create the attributes while you are creating HTML.
But you can do what you want using jquery iterate function (Jquery.each): http://api.jquery.com/jquery.each/
var myElements = $('div.myClass'),
i = 0;
$.each( myElements , function( i ) {
$(this).attr('data-index','index'+(i+1));
});
Try this:
var newAttr = document.createAttribute("data-index");
newAttr.value = "[What you want the index to be]";
// Will set data-index for first .myClass in newElement
newElement.getElementsByClassName("myClass")[0].setAttributeNode(newAttr);
// Will set data-index for every .myClass in newElement
newElement.getElementsByClassName("myClass").map(function(node) {
node.setAttributeNode(newAttr)
});

Append Child Elements to a Child Element in the same parent

How do you append child elements to a sibling using jQuery?
html
<div class="parent">
<div class="child one">...</div>
<div class="child">...</div>
<div class="child">...</div>
</div>
<div class="parent">
<div class="child one">...</div>
<div class="child">...</div>
<div class="child">...</div>
</div>
Script
$('.child').each(function(i, obj){
if(!$(obj).hasClass('one')){
$(obj).appendTo( .. Stuck here .. '.one');
}
});
I can get the parent object but the trouble is then selecting the child with class 'one'.
Essentially I want to move all siblings so that the become children of the first child.
<div class="parent">
<div class="child one">
<div class="child">...</div>
<div class="child">...</div>
</div>
</div>
<div class="parent">
<div class="child one">
<div class="child">...</div>
<div class="child">...</div>
</div>
</div>
You want to append all the child not one into child one?
$('.child').not('.one').appendTo('.one');
THE WORKING DEMO.
Get each element with class one, then append its siblings with class child.
$('.child.one').each(function(i, obj){
$(obj).siblings('.child').each(function(j, child){
$(child).appendTo(obj);
});
});
Working Demo
Note: if you want the child elements outside the one element, replace appendTo with after.
try this:
$('.child').each(function(){
if(!$(this).hasClass('one')){
$(this).appendTo('.one');
}});
Working Demo

Categories