I implemented a popup that appears when a button is pressed, and want the background to be blurred when the popup message is on the screen. I've added a function called toggle() which activates/deactivates when clicking on the button:
function toggle() {
var blur = document.getElementById('blur');
blur.classList.toggle("active");
var popup = document.getElementById('popup');
popup.classList.toggle("active");
var popup2 = document.getElementById('popup2');
popup2.classList.toggle("active");
}
HTML code:
<div class="container" id="blur">
<div class = "col-8" style = "display: flex;">
<div class = "container-buttons">
<div class = "canvas-menu">
<ul>
<li><button id="clear-button" class="btn" onclick="toggle(); displayPopup();"><span style="color: black;">
<i class="fa-solid fa-circle-xmark"> Clear</i>
</span></button></li>
<!-- Content popoup -->
<div class="popup" id="popup">
<p>Are you sure you want to delete blocks?</p>
<button id="no-btn" onclick="toggle(); closePopup()">No</button>
<button id="yes-btn" onclick="toggle(); closePopup(); clearAll();">Yes</button>
</div>
<div class="popup" id="popup2">
<p>There are no blocks to clear :(</p>
<button id="back-btn" onclick="toggle(); closePopup()">Go back</button>
</div>
And these are the CSS attributes I've added:
.container#blur.active {
filter: blur(10px);
pointer-events: none;
user-select: none;
}
#popup.active, #popup2.active {
pointer-events: all;
filter: none;
}
.display-popup {
visibility: visible;
top: 50%;
transform: translate(-50%, -50%) scale(1);
filter: blur(0px);
}
where container is the whole website screen and popup and popup2 are two different popups. Right now, when the button is clicked, the whole website is blurred including the popup message.
I'd appreciate any help :)
(I'm using JavaScript)
I fixed it! I just had to take the popup HTML code out of the HTML container scope and it works perfectly now.
The important thing to remember about CSS is that it cascades; so if your popup is a child of the blur element, it will have blur applied to it. Try changing your markup to ensure the popup is not a child of the blur item and has a higher z-index too.
Related
I've used eventListener to close popups when I click off them but the popup still shows when I click on another popup. Is there a way to fix this without changing too much of my code?
I'm new to JS so I'm keeping things as simple as possible. Ideally I want to keep the eventListener function because it works really well to close the popups without having to manually close each one, apart from this one thing.
var popup = document.getElementById("myPopup");
function myFunction() {
popup.classList.toggle("show");
}
window.addEventListener('click', ({ target }) => {
if (!target.closest('.popup') && popup.classList.contains('show')) myFunction();
});
var popup2 = document.getElementById("myPopup2");
function myFunction2() {
popup2.classList.toggle("show");
}
window.addEventListener('click', ({ target }) => {
if (!target.closest('.popup') && popup2.classList.contains('show')) myFunction2();
});
/* Popup container - can be anything you want */
.popup {
position: relative;
display: inline-block;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/* The actual popup */
.popup .popuptext {
visibility: hidden;
width: 160px;
background-color: #555;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 8px 0;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -80px;
}
/* Popup arrow */
.popup .popuptext::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #555 transparent transparent transparent;
}
/* Toggle this class - hide and show the popup */
.popup .show {
visibility: visible;
-webkit-animation: fadeIn 1s;
animation: fadeIn 1s;
}
<body style="text-align:center">
<h2>Popup</h2>
<div class="popup" onclick="myFunction()">Click me to toggle the popup!
<span class="popuptext" id="myPopup">A Simple Popup!</span>
</div>
<h2>Popup2</h2>
<div class="popup" onclick="myFunction2()">Click me to toggle the popup!
<span class="popuptext" id="myPopup2">A Simple Popup again!</span>
</div>
</body>
You're very close, but the way you've written it is making it difficult. We can better solve this using a forEach loop and generic function:
JSFiddle: https://jsfiddle.net/vpr4Lh62/
// constants
const SHOW_CLASS = 'show'
// clears any active popups by removing the show class from all popup texts
// note: could be further optimized by storing the "active" popup in a variable whenver it's clicked, and only unsetting that one in this function
const clearPopups = () => {
document.querySelectorAll('.popuptext').forEach(text => text.classList.remove(SHOW_CLASS))
}
// keep behavior to clear popups when clicking outside of popup
window.addEventListener('click', ({ target }) => {
if(!target.classList.contains('popup')) {
clearPopups()
}
})
// instead of creating click handlers for each popup, we can create them all at once using a forEach loop
// first grab all the popups on the page
const popups = document.querySelectorAll('.popup')
// set a click handler on each popup
popups.forEach(popup => {
// we can also set the event listener on the popup, instead on the entire window
popup.addEventListener('click', ({ target }) => {
// grab the first child, which will be the span
const span = popup.children[0]
// clear all the popups first
clearPopups()
// then set this one to be shown
span.classList.add(SHOW_CLASS)
})
})
This also means we can simplify our HTML:
<body style="text-align:center">
<h2>Popup</h2>
<!-- You should never use onclick, this is old. Click handlers should be set using javascript -->
<div class="popup">Click me to toggle the popup!
<!-- We also don't need the ID here anymore -->
<span class="popuptext">A Simple Popup!</span>
</div>
<h2>Popup2</h2>
<div class="popup">Click me to toggle the popup!
<span class="popuptext">A Simple Popup again!</span>
</div>
</body>
To keep it as simple and least amount of change (but by far not an ideal solution) is this:
For the window click handlers you need to be able to differentiate between the two popups, currently you are using a .popup class as a check if it's not the closest thing in both cases, so when you click on a second popup, the myFunction() is not executed.
What I added here is new class names to the popups, 'one' and 'two' respectively.
<body style="text-align:center">
<h2>Popup</h2>
<div class="popup one" onclick="myFunction()">Click me to toggle the popup!
<span class="popuptext" id="myPopup">A Simple Popup!</span>
</div>
<h2>Popup2</h2>
<div class="popup two" onclick="myFunction2()">Click me to toggle the popup!
<span class="popuptext" id="myPopup2">A Simple Popup again!</span>
</div>
</body>
Then in your javascript code you can target them by modifying the selectors ever so slightly:
var popup = document.getElementById("myPopup");
function myFunction() {
popup.classList.toggle("show");
}
window.addEventListener('click', ({ target }) => {
if (!target.closest('.popup.one') && popup.classList.contains('show')) myFunction();
});
var popup2 = document.getElementById("myPopup2");
function myFunction2() {
popup2.classList.toggle("show");
}
window.addEventListener('click', ({ target }) => {
if (!target.closest('.popup.two') && popup2.classList.contains('show')) myFunction2();
});
Again, this is by no means a good coding standard nor the best solution but effectively the simplest one with least alteration to the code.
I hope this helps in terms of making sense why the issue occurred in the first place.
This is the solution to your problem.
Mohd Belal Toggle popus JsFiddle
Points covered in this jsfiddle
1. 2 Popus have been taken for now
2. Popus will toggle other popup opened
3. Clicking on area other than popup will close the popup
Hope you got your solution #Joe
I have a div section with a background image with a gradient cover and some text on. I want to control changing this with a java script button. When its clicked it should remove the gradient and show a new div section with different background image no gradient and text. The JQuery underneath is supposed to check whether the first div is showing. and when clicked it should hide the original div and replace it with the new one. I cannot seem to get it working. any help would be appreciated.
/*
jQuery event that triggers when the button is pressed
# is an ID jQuery selector, usage:#anyElementId
*/
$('btnClick').on('click',function(){
/*
In CSS, you can check if an element is visible by checking if the property display value is different from none, because if it's value is none, it will not be visible
*/
if($('call-to-section').css('display')!='none'){
/*
So, if div call-to-section is visible, the condition will be true
*/
$('call-to-section2').show().siblings('div').hide();
}else if($('#call-to-section2').css('display')!='none'){
/*
Condition to check if call-to-section2 is visible
*/
$('call-to-section').show().siblings('div').hide();
/*
If it is, it will show call-to-section and right after that will search for it siblings and hide them with .siblings('div').hide();
*/
}
});
<!-- Call To Action Section
================================================== -->
<section id="call-to" class="call-to-section">
<div class="call-to-layer main-gradient"></div>
<div class="container">
<div class="row">
<div class="col-md-12">
<h3 class="wow fadeIn animated">Global Reach & <span>Demographics.</span></h3>
<p class="wow fadeIn animated">With 3 billion searches per month, YouTubes search
volume is bigger than Bing, AOL, Yahoo and Ask.com combined. If YouTube's user base were a
country,
it would be the third largest in the world. It is the worlds largest site for traffic.
</p>
<button id="btnClick" class="btn btn-default wow fadeInRight hvr-sweep-to-right
button-gradient animated " >Have a look</button>
</div>
</div>
</div>
</section>
<section id="call-to" class="call-to-section2" style= "display:none;">
<div class="call-to-layer main-gradient"></div>
<div class="container">
<div class="row">
<div class="col-md-12">
<h3 class="wow fadeIn animated">Test & <span>Testing</span></h3>
<p class="wow fadeIn animated">This is a new text and total differnt background
picture"
</p>
<button class="btn btn-default wow fadeInRight hvr-sweep-to-right button-gradient
` `animated " id="btnClick" >Have a look</button>
</div>
</div>
</div>
</section>
<!-- /.call-to-section -->
* 9. Call To Action Section
--------------------------------- */
.call-to-section {
height: auto;
width: 100%;
background: url(../images/low-poly.jpg) no-repeat;
background-size: cover;
text-align: center;
position: relative;
padding-top: 146px;
padding-bottom: 146px;
}
.call-to-section2 {
height: auto;
width: 100%;
background-color:#FFF
background-size: cover;
text-align: center;
position: relative;
padding-top: 146px;
padding-bottom: 146px;
I had corrected and obtained the desired result, There was following error in codes written.
1) Both Div element has the same id #call-to, which is actually not required if required for some other purpose please have a separate id for all Div.
2)both Button element also have the same ID #btnClick, change it as #btnClick and #btnClick1
I think id can not be the same for two elements. Read the MDN Web Docs https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id
Complete Code is available in my Codepen https://codepen.io/sanjayism/full/ExVdKpv
$(document).ready(function () {
$("#btnClick").on("click", function () {
if ($(".call-to-section").css("display") == "block") {
$(".call-to-section").css("display", "none");
$(".call-to-section2").css("display", "block");
}
});
$("#btnClick1").on("click", function () {
if ($(".call-to-section2").css("display") == "block") {
$(".call-to-section").css("display", "block");
$(".call-to-section2").css("display", "none");
}
});
});
So I'm a total beginner in javascript and I'm just getting back into the swing of html/css, so I'm all around rusty. W3 is basically my go to and has got me started, but I've scoured google and stack overflow for a simple solution I can understand and I've come up with nothing. Can anyone explain to me what's going wrong with a simple function?
I have a drop down menu that appears from an onclick function attached to a div which basically looks like
function openMobileMenu(){
document.getElementById("mobilelinkmenu").style.display="block";
}
and that works fine, my menu pops up just fine.
When it's time to close that menu I have a <span onclick="closeMobileMenu()"> + </span> inside of that div to act as a closing button, and the code looks like this
function closeMobileMenu(){
document.getElementById("mobilelinkmenu").style.display="hidden";
}
I'm sure I'm making some rookie mistake and nothing can be that simple, but can anyone point to the source of my mistake? I just want to finish this dang menu and move on. Is it because my exit function span is inside of the opening function div and when I'm clicking on the exiting span, it's really just clicking on the opening div?
Here's the code
<div id="navbar" class="mobilemenustyle" onclick="openMobileMenu()">
<img src="images/navicon.jpg" alt="nav" width=10%>
<span onclick="closeMobileMenu()">Nav Menu</span> <span class="exit" onclick="closeMobileMenu()" > + </span>
</div>
<!--opened nav menu--> <div id="mobilelinkmenu" class="mobilemenustyle"> <ul> <li>You Are Here</li> <li>Photography</li> <li>Musicality</li> <li>DJ Life</li> <li>More Me</li> </ul> </div>
<script>
function openMobileMenu(){
document.getElementById("mobilelinkmenu").style.display="block";
document.getElementById("navbar").style.boxShadow="none";
document.getElementById("mobilelinkmenu").style.boxShadow="0px 10px 15px 0px rgba(0,0,0,0.3)";
var exit = document.getElementsByClassName("exit"), i=exit.length;
while(i--){exit[i].style.transform="rotate(45deg)";
}
var exit = document.getElementsByClassName("exit"), i=exit.length;
while(i--){exit[i].style.transition=".5s ease-in-out";
}
}
function closeMobileMenu(){
document.getElementById("mobilelinkmenu").style.display="hidden";
}
</script>
You need to call event.stopPropagation() to stop the click event from bubbling to the div with the id of "navbar" and opening the menu. When you click on the span inside the div, the onclick event handler for it is called (to close the menu), but the event will bubble up to its parent div and call its onclick event handler (opening the menu again). Using event.stopPropagation() will prevent the event from bubbling up the DOM tree.
You also need to change
document.getElementById("mobilelinkmenu").style.display="hidden";
To
document.getElementById("mobilelinkmenu").style.display="none";
"hidden" is an invalid property value for the display CSS property (it can be used with the visibility property).
.rotated{
display: inline-block;
-ms-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.rotated:hover{
color: red;
}
.exit{
-webkit-transition: .5s ease-in-out;
transition: .5s ease-in-out;
}
<div id="navbar" class="mobilemenustyle" onclick="openMobileMenu()">
<img src="images/navicon.jpg" alt="nav" width=10%>
<span onclick="closeMobileMenu(event)">Nav Menu</span> <span class="exit" onclick="closeMobileMenu(event)" > + </span>
</div>
<!--opened nav menu--> <div id="mobilelinkmenu" style="display: none;" class="mobilemenustyle"> <ul> <li>You Are Here</li> <li>Photography</li> <li>Musicality</li> <li>DJ Life</li> <li>More Me</li> </ul> </div>
<script>
function openMobileMenu(){
document.getElementById("mobilelinkmenu").style.display="block";
document.getElementById("navbar").style.boxShadow="none";
document.getElementById("mobilelinkmenu").style.boxShadow="0px 10px 15px 0px rgba(0,0,0,0.3)";
var exit = document.getElementsByClassName("exit"), i=exit.length;
while(i--){
exit[i].classList.add("rotated");
}
}
function closeMobileMenu(e){
e.stopPropagation();
document.getElementById("mobilelinkmenu").style.display="none";
var exit = document.getElementsByClassName("exit"), i=exit.length;
while(i--){
exit[i].classList.remove("rotated");
}
}
</script>
how? when click the .button, hide all .body div tags and show just closest .body tag div
my codes first one works, but when click the .button, show .body, but when click again, does't toggle ( show / hide ) that, any more?
How to do it properly?
Edit : how to change .button > span icon? ( positive or negative )
Edit : jQuery(this).find('positive').toggleClass('negative'); ?
Edit (saitho): JSFiddle: https://jsfiddle.net/nL4sxbj0/2/
HTML
<div class="box">
<div class="header">
<a href="#" class="button">
<span class="positive"></span>
</a>
</div>
<div class="body">
</div>
</div>
CSS
.body {
display:none;
}
.button .positive,
.button .negative {
width:36px;
height:36px;
float:right;
display:block;
cursor:pointer;
}
.button .positive {
background:url('../img/icon-del.png') no-repeat center center / 18px;
}
.button .negative {
background:url('../img/icon-opn.png') no-repeat center center / 18px;
}
JQUERY
jQuery('.button').on('click' ,function(e) {
e.preventDefault(); // Is this necessary? for
jQuery('.body').hide(); // Problem is hear i think
jQuery(this).closest('.box').find('.body').toggle();
});
Picture
add class iconbtn to button span
<div class="box">
<div class="header">
<a href="#" class="button">
<span class="iconbtn positive"></span>
</a>
</div>
<div class="body">
</div>
jQuery('.button').on('click' ,function(e) {
e.preventDefault();
var box = jQuery(this).closest('.box');
var closestBody = box.find('.body');
jQuery('.body').not(closestBody).hide(); // Hide all except above div
jQuery(closestBody).toggle(); // if visible hide it else show it
jQuery('.iconbtn').removeClass('negative').addClass('positive');
var iconBtn = box.find('.iconbtn');
if (jQuery(closestBody).is(':visible')) {
iconBtn.removeClass('positive').addClass('negative');
} else {
iconBtn.removeClass('negative').addClass('positive');
}
});
jsFiddle Link
The issue is that you have:
jQuery('.body').hide();
in your click callback, that means the body div is first being hidden and then toggle works as it should - it shows the div. There is no way it can hide it though, as before toggle you always first hide the div
Remove this line and it should work, check it here: JS Fiddle
This is on my plugin page on Git and I have two interactive demo in the web page. In one of the demo page, I have a small dialog that opens when you click on a div.
The weird issue is that this dialog is getting opened when I click on the top title that says attrchange beta . This happens only if the first click is on the title attrchange beta, clicking any other element in page fixes this issue.
The plugin page http://meetselva.github.io/attrchange/ [Fixed, use the below URL to see the problem]
http://meetselva.github.io/attrchange/index_so_issue.html
Below is the code,
<!-- The title -->
<h1 id="project_title">attrchange <span class="beta" style="text-decoration: line-through;" title="Almost there...">beta</span></h1>
<!-- Main dialog that has link to the sub-dialog -->
<div id="attributeChanger">
<h4 class="title">Attribute Changer</h4>
<p>Listed below are the attributes of the div:</p>
<div class="attrList"></div>
<div class="addAttribute text-right">add new attribute</div>
</div>
<!-- Sub-dialog -->
<div id="addOrmodifyAttr" title="Add/Modify Attribute">
<h4 class="title">Add/Modify Attribute</h4>
<p><b>Attr Name</b> <input type="text" class="float-right attrName"></p>
<p><b>Attr Value</b> <input type="text" class="float-right attrValue"/></p>
<div class="clear"> </div>
<button type="button" class="float-right close">Close</button>
<button type="button" class="float-right update">Update</button>
<div class="clear"></div>
</div>
JS:
var $attributeChanger = $('#attributeChanger');
var $attrName = $('.attrName', '#addOrmodifyAttr'),
$attrValue = $('.attrValue', '#addOrmodifyAttr'),
$attrAMUpdate = $('.update', '#addOrmodifyAttr');
//Handler to open the sub-dialog
$attributeChanger.on('click', '.addAttribute', function () {
$attrName.val('').removeClass('nbnbg');
$attrValue.val('');
$('#addOrmodifyAttr, #overlay').show();
});
The problem is the CSS applied to your #attributeChanger div.
If you look at the CSS applied to it:
#attributeChanger {
background-color: #FEFFFF;
border: 1px solid #4169E1;
color: #574353;
font-size: 0.9em;
margin: 10px;
min-height: 50px;
min-width: 150px;
opacity: 0;
padding: 2px;
position: absolute;
top: -200px;
z-index: 1;
}
You'll notice that the position is absolute, and it's positioned over your logo. So what you're clicking is actually your #attributeChanger div.
To fix it, you can hide #attributeChanger using display: none;, then use $('#attributeChanger').show(); in jQuery when it comes into actual view.
The pop up is showing because this code is running:
}).on('click', '.addAttribute', function () {
$attrName.val('').removeClass('nbnbg');
$attrValue.val('');
$('#addOrmodifyAttr, #overlay').show();
This is because the DIV with the class addAttribute is over the title DIV.
You can either move the 'addAttribute' DIV, or remove the last line of that onclick function.
That is because you element is hover your title and detect the click on himself and open(i don't know why it open, i didnt examine your entire code). But when you click anywhere else, your code is changing his position so it is not over the title.
The easiest fix is to change you #attributeChanger CSS top to -100px (that's the value when you click on the document) OR add a display : none.
EDIT : Axel answer show what I mean by "element is hover your title".