I have a piece of code that shows a div on click of the parent div. I want to be able to hide this child div when I click the parent div again.
I can't figure this out.
I don't understand if it has to be in a separate function or not? How do I check if it was clicked before (maybe if the child div is shown? really confused on how to do that).
Thanks for your help,
document.getElementsByClassName('article-title')[i]
.addEventListener('click', function (event) {
articleDescription.style.display = "block";
}
My code is very very long, but the showing the div on click works perfectly. Hence me not posting the entire code. I just need some help in seeing what direction I need to head into to make it disappear after a second click
The snippet below should work for you. Basically, it uses window.getComputedStyle(this.children[0]).getPropertyValue("display") to check if the element is visible or not. If it is visible, it shows the div. If it is not visible, it hides the div.
https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
articleDescription = document.getElementsByClassName("article-description");
articleTitles = document.getElementsByClassName('article-title');
for (var i = 0; i < articleTitles.length; i++) {
articleTitles[i]
.addEventListener('click', function(event) {
if (window.getComputedStyle(this.children[0]).getPropertyValue("display") == "none") {
this.children[0].style.display = "block";
}
else if (window.getComputedStyle(this.children[0]).getPropertyValue("display") == "block") {
this.children[0].style.display = "none";
}
})
}
.article-title {
width: 300px;
height: 50px;
background-color: red;
}
.article-description {
width: 300px;
height: 50px;
background-color: yellow;
display: none;
}
<div class="article-title">
<div class="article-description"></div>
</div>
<div class="article-title">
<div class="article-description"></div>
</div>
<div class="article-title">
<div class="article-description"></div>
</div>
<div class="article-title">
<div class="article-description"></div>
</div>
<div class="article-title">
<div class="article-description"></div>
</div>
You need to add a condition to check does that child element have the styledisplay:block or not. It's a toggle function.
var articleTitle = document.getElementsByClassName('article-title');
for(let i=0; i<articleTitle.length; i++){
articleTitle[i].addEventListener('click', function (event) {
let target = event.target;
let articleDescription = target.firstElementChild;
articleDescription.style.display = (articleDescription.style.display == 'none') ? 'block' : 'none';
});
};
<div class="article-title">parent
<div class="article-description">child</div>
</div>
<div class="article-title">parent
<div class="article-description">child</div>
</div>
your Problem gets easier if you add classes on your elements and handle the hiding via CSS.
jQuery Example:
$(".parent").click(function(){
$(".parent").toggleClass("clicked");
});
.child{
display: none;
}
.parent.clicked .child{
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent">
parent
<div class="child">child</div>
</div>
Related
I have a set of div elements inside a container, .div-to-hide is displayed by default whilst .div-to-show is hidden.
When I click in .set, .div-to-hide should hide and .div-to-show should be visible. Next click should return the previous clicked element to its default state.
I need to display to buttons on click inside on .div-to-show.
<div class="container">
<div class="set">
<div class="div-to-hide">Some text</div>
<div class="div-to-show"></div>
</div>
<div class="set">
<div class="div-to-hide">Some text</div>
<div class="div-to-show"></div>
</div>
<div class="set">
<div class="div-to-hide">Some text</div>
<div class="div-to-show"></div>
</div>
</div>
So far I have this:
let lastClicked;
$('.container').on('click', function(e) {
if (this == lastClicked) {
lastClicked = '';
$('.div-to-hide').show();
$(this).children('.div-to-hide').hide();
} else {
lastClicked = this;
$('.div-to-hide').hide();
$(this).children('.div-to-hide').show();
$(this).children('.div-to-show').hide();
}
});
Can't get it to work properly tho.. I don't know what I am missing...
Any help is deeply appreciated!
UPDATE: got it working! Thanks everyone!
First, you are not using delegation (second parameter on the $.on() function) to define the .set element as your this inside the function.
If I understood correctly, you want to show the elements on the last one clicked and hide the rest. You don't really need to know which one you last clicked to do that
$('.container').on('click', '.set', function (e) {
// Now "this" is the clicked .set element
var $this = $(this);
// We'll get the children of .set we want to manipulate
var $div_to_hide = $this.find(".div-to-hide");
var $div_to_show = $this.find(".div-to-show");
// If it's already visible, there's no need to do anything
if ($div_to_show.is(":visible")) {
$div_to_hide.show();
$div_to_show.hide();
}
// Now we get the other .sets
var $other_sets = $this.siblings(".set");
// This second way works for more complex hierarchies. Uncomment if you need it
// var $other_sets = $this.closest(".container").find(".set").not(this);
// We reset ALL af them
$other_sets.find(".div-to-show").hide();
$other_sets.find(".div-to-hide").show();
});
Consider using class toggling instead.
$('.set').on('click', function(e) {
$('.set').removeClass('hidden-child');
$(this).addClass('hidden-child');
});
css:
.hidden-child .div-to-hide, .div-to-show {
display: none;
}
.hidden-child .div-to-show, .div-to-hide {
display: block;
}
This will make your code easier to reason about, and lets css control the display (style) rules.
Edit: changed class name for clarity; expanded explanation; corrected answer to conform to question
Try to make use of siblings() jQuery to hide and show other divs and toggle() jQuery to show and hide itself and also you will need to set click() event on .set, not in .container
$(document).on('click', '.set', function(e) {
$(this).find('.hide').toggle();
$(this).find('.show').toggle();
$(this).siblings('.set').find('.hide').show();
$(this).siblings('.set').find('.show').hide();
});
.show {
display: none;
}
.set div {
padding: 10px;
font: 13px Verdana;
font-weight: bold;
background: red;
color: #ffffff;
margin-bottom: 10px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="set">
<div class="hide">1 Hide</div>
<div class="show">1 Show</div>
</div>
<div class="set">
<div class="hide">2 Hide</div>
<div class="show">2 Show</div>
</div>
<div class="set">
<div class="hide">3 Hide</div>
<div class="show">3 Show</div>
</div>
</div>
I have a list of items displayed in a container with a dropdown associated with every container.A snippet of how the container list looks:
http://jsfiddle.net/jHpKB/2/
When I click on the button , the dropdown menu shows up, however, when I try to click on any other button button, the dd stays and does not hide. the list is dynamically created. What I was trying to do is if the current clicked element is same as that of the previous clicked elemnt, then hide the first dd menu
Is there way to check if a clicked element is equal to the previous clicked element in javascript(no jquery)
code:
afterRender: function() {
this.el.on('click', function(e) {
//here i want to check (if e.getTarget() === secondClickedEment) { //do something}
},this);
}
is this possible?
Thanks
You can test object equality with jQuery using the is function. Requires 1.6 or higher.
var stuff = $('#stuff');
var thing = stuff;
if (stuff.is(thing)) {
// the same
}
So for your situation this should work:
afterRender: function() {
this.el.on('click', function(e) {
var clickedElm = $(e.getTarget());
var secondElm = $(secondClickedElm);
if (clickedElm.is(secondElm)){
// same elements
}
},this);
}
jQuery example:
use var lastClicked; to hold the last clicked element, then each click check if the same one clicked then reset the lastclicked, otherwise update the lastclicked.
var lastClicked;
$('.container').on('click', function(e) {
if (this == lastClicked) {
lastClicked = '';
$(this).children('.menu').hide();
} else {
lastClicked = this;
$('.menu').hide();
$(this).children('.menu').show();
}
});
.container {
border: 1px solid #333;
height: 300px;
width: 200px;
float: right;
margin-right: 20px;
}
.menu {
display: none;
}
.button {
border: 1px solid #333;
background: #333;
float: right;
height: 20px;
width: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="button">
</div>
<div class="menu">
<div class="option1 option">option1</div>
<div class="option2 option">option2</div>
</div>
</div>
<div class="container">
<div class="button">
</div>
<div class="menu">
<div class="option1 option">option1</div>
<div class="option2 option">option2</div>
</div>
</div>
<div class="container">
<div class="button">
</div>
<div class="menu">
<div class="option1 option">option1</div>
<div class="option2 option">option2</div>
</div>
</div>
One way to do this would be to dynamically add/remove a class to the div, indicating if it's open or not. Then on click, you could just toggle that class.
Example:
let containers = document.getElementsByClassName('container');
for (let i=0; i<containers.length; i++) {
let button = containers.item(i).getElementsByClassName('button')[0];
let menu = containers.item(i).getElementsByClassName('menu' )[0];
button.addEventListener('click', function() {
menu.classList.toggle('open');
});
}
Then in your CSS:
.open {
display: block;
}
I have a list of DIVS that have buttons inside. By default, all buttons are hidden. When I click within a DIV area, the current button inside of this clicked DIV are should show (class='.db') AND all previously clicked/shown buttons should be hidden (class='.dn'). In other words, at any time there should be only one button (currently clicked) shown and all other should be hidden.
I want to use vanilla Javascript and tried this below, but it won't work. I feel there is some small error but don't know where.. Note - the DIVS and buttons don't have their own unique IDs (they only have the same CSS (.posted) classes.
PS - maybe it'd be better not to add this onClick="t();" to each DIV and use an 'addEventListener' function, but this is way too much for me ; )
CSS:
.dn {display:none}
.db {display:block}
.posted {
height: 50px;
width: 100px;
background-color: green;
border: 2px solid red;
}
HTML:
<div class="posted" onClick="t();">
<button class="dn">Reply</button>
</div>
<div class="posted" onClick="t();">
<button class="dn">Reply</button>
</div>
<div class="posted" onClick="t();">
<button class="dn">Reply</button>
</div>
JAVASCRIPT:
function t()
{
var x=document.getElementsByClassName("posted"),i,y=document.getElementsByTagName("button");
for(i=0;i<x.length;i++)
{
x[i].y[0].className="dn";
};
x.y[0].className='db';//make sure the currently clicked DIV shows this button (?)
}
You might want to read more about selector, how to select class, block level etc.
some link might be helpful:
CSS selector:
https://www.w3schools.com/cssref/css_selectors.asp
jQuery selector:
https://api.jquery.com/category/selectors/
Solution - Using jQuery:
$('.posted').on('click', function() {
//find all class called posted with child called dn, then hide them all
$('.posted .dn').hide();
//find this clicked div, find a child called dn and show it
$(this).find('.dn').show();
});
.dn {
display: none
}
.db {
display: block
}
.posted {
height: 50px;
width: 100px;
background-color: green;
border: 2px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="posted">
<button class="dn">Reply1</button>
</div>
<div class="posted">
<button class="dn">Reply2</button>
</div>
<div class="posted">
<button class="dn">Reply3</button>
</div>
Solution - Pure js version:
//get list of div block with class="posted"
var divlist = Array.prototype.slice.call(document.getElementsByClassName('posted'));
//for each div
divlist.forEach(function(item) {
//add click event for this div
item.addEventListener("click", function() {
//hide all button first
divlist.forEach(function(el) {
el.getElementsByTagName('button')[0].classList.add('dn');
});
//show button of the div clicked
this.getElementsByTagName('button')[0].classList.remove('dn');
}, false);
});
.dn {
display: none
}
.db {
display: block
}
.posted {
height: 50px;
width: 100px;
background-color: green;
border: 2px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="posted">
<button class="dn">Reply1</button>
</div>
<div class="posted">
<button class="dn">Reply2</button>
</div>
<div class="posted">
<button class="dn">Reply3</button>
</div>
You can do this with with plain JavaScript using Event Bubbling, querySelector and the element classList attribute like this.
Change your HTML to look like this:
<div class="posts">
<div class="posted">
<button class="dn">Reply</button>
</div>
<div class="posted" >
<button class="dn">Reply</button>
</div>
<div class="posted" >
<button class="dn">Reply</button>
</div>
</div>
Then use JavaScript like this:
var posts = document.querySelector('.posts');
var allPosted = document.querySelectorAll('.posted');
//clicks bubble up into the posts DIV
posts.addEventListener('click', function(evt){
var divClickedIn = evt.target;
//hide all the buttons
allPosted.forEach(function(posted){
var postedBtn = posted.querySelector('button');
postedBtn.classList.remove('db');
});
// show the button in the clicked DIV
divClickedIn.querySelector('button').classList.add('db')
});
You can find a working example here: http://output.jsbin.com/saroyit
Here is very simple example using jQuery .siblings method:
$(function () {
$('.posted').click(function () {
$('button', this).show();
$(this).siblings().find('button').hide();
});
});
https://jsfiddle.net/3tg6o1q7/
First, all three line of text will visible. Those are in different div. When I hover on IMAGE 1, only the first div should visible and other two should be hidden.
Like this, If I hover on IMAGE 3, only the third div text or 3rd line should visible and other line should hide.
Can you please sugget me how to achive that? Or can you give me a working example or code please? I tried using different way but failed.
Please check the html code in jsfiddle.
https://jsfiddle.net/mdykabir/ex67pfs1/2/
<div class="images">
<img src="http://www.mykabir.info/wp-content/uploads/2017/01/1.png">
<img src="http://www.mykabir.info/wp-content/uploads/2017/01/2.png">
<img src="http://www.mykabir.info/wp-content/uploads/2017/01/3.png">
</div>
<div class="infoArea">
<div id="infOne">
Show this div if hover on image 1.
</div>
<div id="infTwo">
Show this div if hover on image 2.
</div>
<div id="infThree">
Show this div if hover on image 3.
</div>
<div>
You add an event handler for mouseover/mouseout on the images, like this, and then toggle a class which hides/shows the div
window.addEventListener('load', function() {
var images = document.querySelectorAll('.images > img');
var divs = document.querySelectorAll('.infoArea > div');
for (i = 0; i < images.length; i++) {
(function(i){
images[i].addEventListener('mouseover', function(e) {
document.querySelector('.infoArea').classList.toggle('hide');
divs[i].classList.toggle('show');
})
images[i].addEventListener('mouseout', function(e) {
document.querySelector('.infoArea').classList.toggle('hide');
divs[i].classList.toggle('show');
})
})(i);
}
})
.infoArea.hide div {
display: none;
}
.infoArea > div.show {
display: block;
}
<div class="images">
<img src="http://www.mykabir.info/wp-content/uploads/2017/01/1.png">
<img src="http://www.mykabir.info/wp-content/uploads/2017/01/2.png">
<img src="http://www.mykabir.info/wp-content/uploads/2017/01/3.png">
</div>
<div class="infoArea">
<div id="infOne">
Show this div if hover on image 1.
</div>
<div id="infTwo">
Show this div if hover on image 2.
</div>
<div id="infThree">
Show this div if hover on image 3.
</div>
<div>
With a small markup change you don't even need script, just CSS hover
.images {
display: inline-block;
}
.images:hover ~ .infoArea > div {
display: none;
}
.images.imgOne:hover ~ .infoArea #infOne,
.images.imgTwo:hover ~ .infoArea #infTwo,
.images.imgThree:hover ~ .infoArea #infThree {
display: block;
}
<div class="images imgOne">
<img src="http://www.mykabir.info/wp-content/uploads/2017/01/1.png">
</div>
<div class="images imgTwo">
<img src="http://www.mykabir.info/wp-content/uploads/2017/01/2.png">
</div>
<div class="images imgThree">
<img src="http://www.mykabir.info/wp-content/uploads/2017/01/3.png">
</div>
<div class="infoArea">
<div id="infOne">
Show this div if hover on image 1.
</div>
<div id="infTwo">
Show this div if hover on image 2.
</div>
<div id="infThree">
Show this div if hover on image 3.
</div>
<div>
Based on a comment, here is a sample how to toggle on click, with persistent result
window.addEventListener('load', function() {
var images = document.querySelectorAll('.images > img');
var divs = document.querySelectorAll('.infoArea > div');
for (i = 0; i < images.length; i++) {
(function(i,old){
images[i].addEventListener('click', function(e) {
old = document.querySelector('.infoArea .show');
if (old) {
old.classList.toggle('show');
}
if (old != divs[i]) {
divs[i].classList.toggle('show');
}
})
})(i);
}
})
.infoArea div {
display: none;
}
.infoArea > div.show {
display: block;
}
<div class="images">
<img src="http://www.mykabir.info/wp-content/uploads/2017/01/1.png">
<img src="http://www.mykabir.info/wp-content/uploads/2017/01/2.png">
<img src="http://www.mykabir.info/wp-content/uploads/2017/01/3.png">
</div>
<div class="infoArea">
<div id="infOne">
Show this div if hover on image 1.
</div>
<div id="infTwo">
Show this div if hover on image 2.
</div>
<div id="infThree">
Show this div if hover on image 3.
</div>
<div>
You can use the mouseover and mouseout DOM events.
Here's a minimal example that accomplishes what you want with your example:
function showOnHover(args) {
var trigger = args.trigger;
var target = args.target;
trigger.addEventListener('mouseover', function(e) {
target.style.display = 'block';
})
trigger.addEventListener('mouseleave', function(e) {
target.style.display = 'none';
})
}
var images = document.querySelectorAll('.images img');
var toShow = document.querySelectorAll('.infoArea div');
var triggersAndTargets = Array.prototype.map.call(images, function (img, i) {
return { trigger: img, target: toShow[i] };
});
triggersAndTargets.forEach(showOnHover);
Try it here: https://jsfiddle.net/ex67pfs1/16/
And for an ES2015 version: https://jsfiddle.net/ex67pfs1/18/
Checkout this previous SO question for a jQuery solution.
This is how you do this in plain JS, I would stay away from CSS solutions if you target non sibling elements. If you target the element or a sibling, then do it with CSS, otherwise, there is now ay around JS.
This JS code can be done bit better, I will pack all into one function, but adding the listeners is a must.
var pic1 = document.getElementById('first');
var pic2 = document.getElementById('sec');
var pic3 = document.getElementById('thi');
pic1.addEventListener('mouseenter', function(){
var div1 = document.getElementById('infOne');
div1.style.opacity=1;
});
pic1.addEventListener('mouseout', function(){
var div1 = document.getElementById('infOne');
div1.style.opacity=0;
});
Check it out here, I changed some css as well.
https://jsfiddle.net/ex67pfs1/15/
I'm playing around with building a basic modal window and i want it do dissapear when i click the edges. So my problem in it's most basic form:
<div style="width:100%;height:100%;" onclick="hideAll()">
Hide all onclick.
<div style="width:100px;height:100px;">
does not hide all onclick
</div>
</div>
What is the best way to achieve this? To use unnested divs? html/css magic?
HTML:
<div style="width:100%;height:100%;" class="outerModal">
Hide all onclick.
<div style="width:100px;height:100px;">
does not hide all onclick
</div>
</div>
JavaScript:
$(document).on("click", ".outerModal", function(evt) { //listen for clicks
var target = $(evt.target ||evt.srcElement); //get the element that was clicked on
if (target.is(".outerModal")) { //make sure it was not a child that was clicked.
//hide dialog
}
});
Example:
JSFiddle
When you hide the parent tag, it automatically hides the childen tag as well, You should first contain the child div into variable and after that hide the parent div and append that stored child div into parent tag something like this.
HTML
<div id="result">
<div style="width:100%;height:100%;" id="parentDiv" onclick="hideAll()">
Hide all onclick.
<div style="width:100px;height:100px;" id="childDiv">
does not hide all onclick
</div>
</div>
</div>
javaScript
function hideAll(){
var childDiv = document.getElementById('childDiv'); //contain child div
var parDiv = document.getElementById('parentDiv');
parDiv.style.display = 'none'; //hide parent div
parDiv.parentNode.appendChild(childDiv); //append child div
}
DEMO
Assuming that "parentDiv" is to be the background and "childDiv" is to be the actual modal content, the best way I have found is to separate the divs entirely.
HTML
<div id="parentDiv" onclick="hideAll()"> </div>
<div id="childDiv" >
does not hide all onclick
</div>
Javascript using jQuery
function hideAll(){
/* The Parent Div will hide everything when clicked, but the child won't */
$('#childDiv').fadeOut(1000, function(){
$('#parentDiv').fadeOut(1000);
});
}
CSS
#parentDiv {
background: black;
display: block;
position: fixed;
top: 0;
left: 0;
z-index: 100;
height: 100%;
width: 100%;
}
#childDiv {
display: block;
position: relative;
background: white;
height: 200px;
width: 200px;
z-index: 101
}
Here is a working example.
Hope this helps at all.
See this fiddle:
http://jsfiddle.net/eZp9D/
$(document).ready(function () {
$('#parentDiv').click(function (e) {
if ($(e.target).prop('id') == "parentDiv") {
$(this).hide();
}
});
});
You can use basic jQuery and style it accordingly with CSS.
Check this example.
If you want to have it disappear by clicking outside of the dialog window, make sure that onClick you perform this action:
$( "#dialog_id" ).dialog( "close" );