I'm new to the wold of programming and have run into a bit of trouble making a photo gallery with JS.
So, the thumbnails invoke a modal with the appropriate image that is passed via an index as parameter. I've used a bit of JQuery just to attach handler on all the thumbnails without looping.
The very first Modal initialization works fine, I'm able to switch between images and then close the modal just fine. After that if I reinitialize the modal, the first image appears correct but when using the "Next" and "Previous" buttons another image appears in the modal. After closer inspection (and a bunch of variable logs) I've determined that the old index (from the first modal initialization) persists within the program thus the function is running the previous index and the new one passed to it. The more times you close it the more index variables you have. It almost seems like the function is running multiple copies of itself and appending all those images onto that one modal.
Sorry if this is a very obvious mistake. I don't really post on this forum but try to solve it myself however after like 6 hours and 50 Chrome tabs, I'm just about done. Thanks a lot! Here's my code:
https://jsfiddle.net/5yejqw8a/4/#&togetherjs=M77M8B8LU8
$(document).ready(function(){
$('.GalleryImg').on('click', function() { //Attach event handler on each photo
var GalleryImgs = Array.prototype.slice.call(document.getElementsByClassName('GalleryImg')); //Turns object array to an a proper array
var ImgIndex = GalleryImgs.indexOf(this); //Position of img clicked
OpenModal(ImgIndex); //Passes the index into the modal function
});
function OpenModal(n) { //Modal function with index parameter
var SlideIndex = n;
console.log("Start Index = "+SlideIndex);
var Lightbox = document.getElementById("Lightbox");
var Modal = document.getElementById("ModalContent");
var Slides = document.getElementsByClassName("ModalSlides");
Lightbox.style.display = "block";
Slides[SlideIndex].style.display = "block";
var PreviousBtn = document.getElementById("PreviousBtn");
PreviousBtn.addEventListener('click', function() {
if (SlideIndex > 0) {
Slides[SlideIndex].style.display = "none";
SlideIndex --;
Slides[SlideIndex].style.display = "block";
console.log("PCurrent = "+SlideIndex);
} else {
return;
};
});
var NextBtn = document.getElementById("NextBtn");
NextBtn.addEventListener('click', function() {
if (SlideIndex < Slides.length-1) {
console.log(SlideIndex);
Slides[SlideIndex].style.display = "none";
SlideIndex ++;
Slides[SlideIndex].style.display = "block";
console.log("NCurrent = "+SlideIndex);
} else {
return;
};
});
var CloseBtn = document.getElementById("CloseBtn");
CloseBtn.addEventListener('click', function() {
Lightbox.style.display = "none";
var i = 0;
while (i < Slides.length) {
Slides[i].style.display = "none";
i++
};
console.log("Closing Index = "+SlideIndex);
});
};
});
You are getting that because of this structure:
function OpenModal(n) {
var PreviousBtn = document.getElementById("PreviousBtn");
PreviousBtn.addEventListener('click', function() {
// ...
});
var NextBtn = document.getElementById("NextBtn");
NextBtn.addEventListener('click', function() {
// ...
});
var CloseBtn = document.getElementById("CloseBtn");
CloseBtn.addEventListener('click', function() {
// ...
});
}
Each time OpenModal is called, it is adding new event listeners to PreviousBtn, NextBtn and CloseBtn. So the more you click, the more functions are to be called by the listeners.
Here is an example:
var activate = document.getElementById("activate");
activate.addEventListener("click", event => {
var submit = document.getElementById("submit");
var result = document.getElementById("result");
let i = 0;
result.textContent = "";
submit.addEventListener("click", event => {
result.textContent += ' ' + i++;
});
});
body { background: #fafafa }
#result, #hint {
font-family: fantasy;
background: #def;
padding: .5em;
}
#result {
background: #fde;
height: 3em;
}
<div id="hint">
Click on activate, then click submit many times.
<br> Click activate again and click submit again many times.
</div>
<div id="result">Result will come here.</div>
<button id="activate">Activate</button>
<button id="submit">Submit</button>
In the snippet, if you activate then submit five times, and repeat doing that four times, you get :
0 1 2 3 4
5 0 6 1 7 2 8 3 9 4
10 5 0 11 6 1 12 7 2 13 8 3 14 9 4
15 10 5 0 16 11 6 1 17 12 7 2 18 13 8 3 19 14 9 4
because every time activate is clicked, a new listener is added with a new i.
So what you should have is:
var PreviousBtn = document.getElementById("PreviousBtn");
PreviousBtn.addEventListener('click', function() {
// ...
});
var NextBtn = document.getElementById("NextBtn");
NextBtn.addEventListener('click', function() {
// ...
});
var CloseBtn = document.getElementById("CloseBtn");
CloseBtn.addEventListener('click', function() {
// ...
});
function OpenModal(n) {
// ...
}
That way, the listener is added only once.
Because you are adding every time a new listener to PreviousBtn, NextBtn and CloseBtn. You need to define the listeners them outside the OpenModal function or use every time removeEventListener (which doesn't make any sense) for every event listener you defined.
A good possible way could be this:
// Gallery Lightbox
$(document).ready(function(){
var SlideIndex = 0;
var Lightbox = document.getElementById("Lightbox");
var Modal = document.getElementById("ModalContent");
var Slides = document.getElementsByClassName("ModalSlides");
$('.GalleryImg').on('click', function() { //Attach event handler on each photo
var GalleryImgs = Array.prototype.slice.call(document.getElementsByClassName('GalleryImg')); //Turns object array to an a proper array
var ImgIndex = GalleryImgs.indexOf(this); //Position of img clicked
SlideIndex = ImgIndex; //Passes the index into the modal function
Lightbox.style.display = "block";
Slides[SlideIndex].style.display = "block";
});
var PreviousBtn = document.getElementById("PreviousBtn");
PreviousBtn.addEventListener('click', function() {
if (SlideIndex > 0) {
Slides[SlideIndex].style.display = "none";
SlideIndex --;
Slides[SlideIndex].style.display = "block";
console.log("PCurrent = "+SlideIndex);
} else {
return;
}
});
var NextBtn = document.getElementById("NextBtn");
NextBtn.addEventListener('click', function() {
if (SlideIndex < Slides.length-1) {
console.log(SlideIndex);
Slides[SlideIndex].style.display = "none";
SlideIndex ++;
Slides[SlideIndex].style.display = "block";
console.log("NCurrent = "+SlideIndex);
} else {
return;
}
});
var CloseBtn = document.getElementById("CloseBtn");
CloseBtn.addEventListener('click', function() {
Lightbox.style.display = "none";
var i = 0;
while (i < Slides.length) {
Slides[i].style.display = "none";
i++
}
console.log("Closing Index = "+SlideIndex);
});
});
/* Gallery */
.Gallery {
display: block;
position: relative;
width: 100%;
height: auto;
}
.GalleryImg {
height: auto;
width: 100%;
cursor: pointer;
opacity: 1;
transition: transform 0.5s;
transform-origin: 50% 50%;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
.Gallery img:hover {
transform: scale(1.07);
}
/* Lightbox */
#Lightbox {
display: none;
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
padding-top: 5%;
z-index: 10;
background-color: rgba(0,0,0,0.7);
overflow: auto;
}
#ModalContent {
position: relative;
margin: auto;
width: 90%;
max-width: 1200px;
}
.ModalSlides {
display: none;
position: relative;
width: 100%;
height: auto;
}
#CloseBtn {
color: white;
position: absolute;
top: 10px;
right: 25px;
font-size: 50px;
font-weight: bold;
cursor: pointer;
user-select: none;
-webkit-user-select: none;
z-index: 999;
}
#CloseBtn:hover,
#CloseBtn:focus {
color: #999;
text-decoration: none;
cursor: pointer;
}
#NextBtn, #PreviousBtn {
cursor: pointer;
position: absolute;
top: 60%;
width: auto;
padding: 20px;
margin-top: -75px;
color: white;
font-weight: bold;
font-size: 50px;
transition: 0.5s ease;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none;
}
#NextBtn {
right: 0;
border-radius: 3px 0 0 3px;
}
#NextBtn:hover,
#PreviousBtn:hover {
background-color: rgba(0, 0, 0, 0.8);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="Gallery">
<div class="row mt-3">
<div class="col-4">
<img class="GalleryImg" src="http://via.placeholder.com/350x150" alt="">
</div>
<div class="col-4">
<img class="GalleryImg" src="http://via.placeholder.com/380x150" alt="">
</div>
<div class="col-4">
<img class="GalleryImg" src="http://via.placeholder.com/450x150" alt="">
</div>
</div>
<div class="row mt-3">
<div class="col-4">
<img class="GalleryImg" src="http://via.placeholder.com/390x150" alt="">
</div>
<div class="col-4">
<img class="GalleryImg" src="http://via.placeholder.com/350x50" alt="">
</div>
<div class="col-4">
<img class="GalleryImg" src="http://via.placeholder.com/350x250" alt="">
</div>
</div>
</div>
<div id="Lightbox">
<span id="CloseBtn">×</span>
<div id="ModalContent">
<img class="ModalSlides" src="http://via.placeholder.com/350x150" alt="">
<img class="ModalSlides" src="http://via.placeholder.com/380x150" alt="">
<img class="ModalSlides" src="http://via.placeholder.com/450x150" alt="">
<img class="ModalSlides" src="http://via.placeholder.com/390x150" alt="">
<img class="ModalSlides" src="http://via.placeholder.com/350x50" alt="">
<img class="ModalSlides" src="http://via.placeholder.com/350x250" alt="">
<a id="PreviousBtn">❮</a>
<a id="NextBtn">❯</a>
</div>
</div>
In this way we have defined only one time the event listeners.
SlideIndex, Lightbox, Modal and Slides variables are defined at the begin.
Related
I've created a timer that switches and loops between images.
I'm looking to create a pause in between the images in which nothing is shown.
So logo1 on for 15 seconds
hide images for 30 seconds
logo2 on for 15 seconds
and so on
This is what I've got so far.
Ideally, the hide would hide both DIVS
<html>
<head>
<style>
.box1 {
background-color: rgba(0,0,0,0);
color: #fff;
opacity: 1;
align-content: safe;
}
.brandlogo {
background-color: rgba(0,0,0,0);
position: absolute;
top: 500;
left: 1100;
}
.box2 {
background-color: rgba(0,0,0,0);
color: #545454;
position: absolute;
top: 400;
left: 1000;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="box box1" id="art">
<img class="brandlogo" id="image" src="logo1.png" width="100">
</div>
<div class="box box2" id="frameart">
<img class="brandframe" id="frame" src="adframe2.png" width="300">.
</div>
</div>
<script type="text/javascript">
var image = document.getElementById("image");
var currentPos = 0;
var images = ["logo1.png", "logo2.png", "logo3.png"]
function timercount() {
if (++currentPos >= images.length)
currentPos = 0;
image.src = images[currentPos];
}
setInterval(timercount, 3000);
$("#art").show();
setTimeout(function() {
$("#art").hide();
}, 500);
</script>
</body>
</html>
Let me know how it goes :)
<script type = "text/javascript">
var image = document.getElementById("image");
var currentPos = 0;
var images = ["logo1.png", "logo2.png", "logo3.png"]
// jquery api on hide
// https://api.jquery.com/hide/
function hideArt() {
$("#art").hide(30000, changeLogo);
}
function changeLogo() {
if (++currentPos >= images.length) {
currentPos = 0;
}
image.src = images[currentPos];
// restart loop
loop();
}
function loop() {
// setTimeout api
// https://developer.mozilla.org/en-US/docs/Web/API/setTimeout
setTimeout(hideArt, 15000);
}
// start loop
loop();
</script>
I have built a modal by pure html, CSS, javascript.
It would pop-up as I click a button on the main page.
However, if I scroll down the model and close it, it would show the scrolled-down view as I reopen it. How can I make it always show the content at the top each time I open the model?
Here is my code:
<div class="button" id="btn"></div>
<div class="modal" id="mymdl">
<div class="modal-content" id="mdl-con">
<div class="modalwidth">
<img class="image-title" id="img-ttl" src="./img/banner.png">
<span class="close" aria-hidden="true">×</span>
</div>
<div class="paragraph">
Here is the main content.
</div>
</div>
</div>
document.getElementById('btn').addEventListener('click', function(e) {
modal.style.display = "block";
});
var closeX = document.getElementsByClassName("close")[0];
closeX.onclick = function() {
modal.style.display = "none";
}
I have tried window.scroll method provided in the solution of this problem, but it didn't solve my problem.
I'm new to html, css, and javascript. Any idea would be appreciated! Thanks in advance.
Here's one way, rather than scroll to the top, bring the modal top to you.
document.getElementById('btn').addEventListener('click', function(e) {
modal.style.display = "block";
modal.style.top = window.pageYOffset + 10 + "px";
});
const modal = document.querySelector('.modal')
const btns = document.querySelectorAll('.btn');
for (let x = 0; x < btns.length; x++) {
btns[x].addEventListener('click', function(e) {
modal.style.display = "block";
modal.style.top = window.pageYOffset + 10 + "px";
console.log(window.pageYOffset, modal.style.top);
});
}
.container {
height: 1000px;
}
.btn {
display: inline-block;
margin-top: 400px;
}
.modal {
padding: 20px;
position: absolute;
width: 200px;
background: rgba(0, 0, 0, .5);
color: #fff;
}
<div class='container'>
<div class='modal'>Modal</div>
<button class='btn'>click</button>
<hr>
<button class='btn'>click</button>
</div>
You can use element.scrollTop = 0 to scroll it to the top.
For example if .paragraph is what's getting scrolled, you can use something like this:
const modal = document.getElementById("mymdl");
document.getElementById('btn').addEventListener('click', function(e) {
modal.style.display = "block";
});
var closeX = document.getElementsByClassName("close")[0];
closeX.onclick = function() {
modal.querySelector(".paragraph").scrollTop = 0; //scroll to the top
modal.style.display = "none";
}
.modal
{
position: fixed;
}
.modal-content
{
border: 1px solid black;
}
.paragraph
{
overflow: auto;
height: 50vh;
white-space: pre;
text-align: center
}
.paragraph > div
{
height: 120%;
}
.paragraph > span
{
position: relative;
bottom: 0;
}
.button,
.close
{
cursor: pointer;
}
<div class="button" id="btn">open modal</div>
<div class="modal" id="mymdl">
<div class="modal-content" id="mdl-con">
<div class="modalwidth">
<img class="image-title" id="img-ttl" src="./img/banner.png">
<span class="close" aria-hidden="true">×</span>
</div>
<div class="paragraph">
<div>Here is the main content.
scroll down</div><span>bottom</span>
</div>
</div>
</div>
I am having webpage consisting of a range slider which is having three values 1,2,3 for every value there will be change in image,some phrase now my requirement is on page refresh the range slider is setting to the one I dont want it I want it to restore its last dragged position along with image and phrase even on page refresh
My CSS code:
<style>
.rangeslider {
width: 50%;
margin: 0 auto;
position: absolute;
}
.myslider {
-webkit-appearance: none;
background: white;
width: 100%;
height: 20px;
opacity: 0.8;
margin-top: 180px;
}
.myslider::-webkit-slider-thumb {
-webkit-appearance: none;
cursor: pointer;
background: #000080;
width: 33%;
height: 20px;
}
.myslider:hover {
opacity: 1;
}
.image {
position: relative;
width: 400px;
margin: 0 auto;
}
.image>img {
position: absolute;
display: none;
}
.image>img.visible,
.image>img:first-child {
display: block;
}
#sliderOutput>div {
display: none;
}
#sliderOutput>div.visible,
#sliderOutput>div:first-child {
display: block;
}
</style>
My Html code:
<div class="image mt-3 mb-3" id="sliderImages">
<img src="/static/images/1.jpg" width="400" height="180"><!--Image1-->
<img src="/static/images/2.jpg" width="400" height="180"><!--Image2-->
<img src="/static/images/3.jpg" width="400" height="180"><!--Image3-->
</div><br><!-- End of Image sliding-->
<!--Range slider starts-->
<div class="rangeslider">
<input type="range" min="1" max="3" value="1" class="myslider" id="sliderRange" onload="showVal(this.value)">
<div class="container">
<div id="sliderOutput">
<div class="col-4" id="range_1">
<h6 class="display-6 mt-3" ><b><center>Starting from scratch</center></b></h6>
<p class="demo"><center>I'm designing the room </p>
</div>
<div class="col-4" id="range_2">
<h6 class="display-6 mt-3"><b>Somewhere in Between</b></h6>
<p class="demo">I'm designing around a few pieces I already own</p>
</div>
<div class="col-4" id="range_3">
<h6 class="display-6 mt-3"><b>Mostly furnished</b></h6>
<p class="demo">I want to put the finishing touches on my room</p>
</div>
</div><!--End of Range slider-->
My Js code:
window.onload = function()
{
var imagePath = "../static/images/";
var localStorageSliderNumber;
var localStorageImagePath;
if (window.localStorage.getItem('sliderValue') != null) {
localStorageSliderNumber = window.localStorage.getItem('sliderValue');
} else {
window.localStorage.setItem('sliderValue', '1');
localStorageSliderNumber = 1;
}
if (window.localStorage.getItem('imagePath') != null) {
imagePath = imagePath + window.localStorage.getItem('imagePath') + ".jpg";
}
var rangeslider = document.getElementById("sliderRange");
var output = document.getElementById("sliderOutput");
var images = document.getElementById("sliderImages");
rangeslider.addEventListener('input', function() {
for (var i = 0; i < output.children.length; i++) {
output.children[i].style.display = 'none';
images.children[i].style.display = 'none';
}
i = Number(this.value) - 1;
output.children[i].style.display = 'block';
images.children[i].style.display = 'block';
window.localStorage.setItem('imagepath', rangeslider.getAttribute('value'));
window.localStorage.setItem('sliderValue', (i+1));
});
}
Here I am storing the value in the local storage i.e slidervalue but now I want to retain the last dragged position of the rangeslider along with phrase and image
[1]: https://codepen.io/lakshmi123__/pen/abzYeLP
Here you go.
You just need to call your setter methods on load as well. What I've done is, I've segregated the common code for setting the data separately and called it both on load and on value change. Here's an updated code.
window.onload = function() {
var imagePath = "../static/images/";
var localStorageSliderNumber;
var localStorageImagePath;
if (window.localStorage.getItem('sliderValue') != null) {
localStorageSliderNumber = window.localStorage.getItem('sliderValue');
} else {
window.localStorage.setItem('sliderValue', '1');
localStorageSliderNumber = 1;
}
if (window.localStorage.getItem('imagePath') != null) {
imagePath = imagePath + window.localStorage.getItem('imagePath') + ".jpg";
}
var rangeslider = document.getElementById("sliderRange");
var output = document.getElementById("sliderOutput");
var images = document.getElementById("sliderImages");
rangeslider.value = localStorageSliderNumber;
//The common line of code extracted into a method
setData(rangeslider, output, images, localStorageSliderNumber);
rangeslider.addEventListener('input', function() {
//call the method once again
setData(rangeslider, output, images, this.value);
});
}
function setData(rangeslider, output, images, value) {
for (var i = 0; i < output.children.length; i++) {
output.children[i].style.display = 'none';
images.children[i].style.display = 'none';
}
i = Number(value) - 1;
output.children[i].style.display = 'block';
images.children[i].style.display = 'block';
window.localStorage.setItem('imagepath', rangeslider.getAttribute('value'));
window.localStorage.setItem('sliderValue', (i + 1));
window.localStorage.setItem('sliderPosition', (i + 1))
}
Here's the Updated Pen
//Overlay mobile menu open
$('#burger-icon').on('click', function(e) {
e.stopPropagation();
document.getElementById('fp-menu').style.height = "100%";
let overlay_content = document.getElementsByClassName("overlay-content")[0];
let pipe = overlay_content.querySelector(".pipe");
let contact = document.querySelector("#sidebar-leftButton");
let case_studies = document.querySelector("#sidebar-rightButton");
if (screen.width < 1000) {
let overlay_contentA = document.querySelectorAll(".overlay a");
for (i = 0; i < overlay_contentA.length; i++) {
overlay_contentA[i].style.color = "white";
}
//changes the social icons to white if in mobile view.
document.getElementById('instagram').src = "instagram_white.svg";
document.getElementById('linkedin').src = "linkedin_white.svg";
document.getElementById('twitter').src = "twitter_white.svg";
//gets rid of the pipe in menu that is visible for the desktop version
//removes sidetabs while in overlay menu
pipe.style.display = "none";
contact.style.display = "none";
case_studies.style.display = "none";
//changes how the elements are displayed when overlay is triggered
$('#fp-menu .news').removeClass("col-sm-2");
$('#fp-menu .portfolio').removeClass("col-sm-3");
$('#fp-menu #social').removeClass("col-sm-6");
}
});
function closeOverlayMenu() { //closes the overlay mobile menu
// e.stopPropagation();
$('#fp-menu').animateCss('slideUp');
$('#fp-menu').css('height', 0);
let overlay_content = document.getElementsByClassName("overlay-content")[0];
let pipe = overlay_content.querySelector(".pipe");
let contact = document.querySelector("#sidebar-leftButton");
let case_studies = document.querySelector("#sidebar-rightButton");
let overlay_contentA = document.querySelectorAll(".overlay a");
for (i = 0; i < overlay_contentA.length; i++) {
overlay_contentA[i].style.color = "black";
}
//changes icons to black on slide up of overlay
document.getElementById('instagram').src = "instagram.svg";
document.getElementById('linkedin').src = "linkedin.svg";
document.getElementById('twitter').src = "twitter.svg";
//restores elements of the original homepage that were hidden for overlay
pipe.style.display = "block";
contact.style.display = "block";
case_studies.style.display = "block";
$('#fp-menu .news').addClass("col-sm-2");
$('#fp-menu .portfolio').addClass("col-sm-3");
$('#fp-menu #social').addClass("col-sm-6");
};
document.getElementsByTagName('body')[0].onresize = function() {
closeOverlayMenu();
};
//overlay mobile menu close
$('#closebtn').on('click', function(e) {
e.stopPropagation();
$('#fp-menu').animateCss('slideUp');
$('#fp-menu').css('height', 0);
//if overlay mobile menu is down, close it by clicking the X
if (screen.width < 1000) {
closeOverlayMenu();
console.log(document.querySelectorAll("#social"));
}
});
//overlay menu styling
.overlay {
height: 0;
width: 100%;
position: fixed;
z-index: 999;
top: 0;
left: 0;
background-color: #000000;
overflow-x: hidden;
transition: 0.5s;
}
.overlay-content {
position: relative;
top: 5%;
width: 100%;
text-align: center !important;
margin-top: 90px;
.row{
padding: 50px 30px 50px 30px;
.column{
float: left;
width: 33.33%;
padding: 0 5px 0 5px;
}
}
img {
width: 50px;
}
div {
padding: 30px 0 30px 0;
}
}
.overlay a {
padding: 8px;
text-decoration: none;
font-size: 36px;
color: #FFFFFF;
}
.overlay a:hover, .overlay a:focus {
color: #f1f1f1;
}
#closebtn {
display:block;
position: relative;
top: 5px;
right: 20px;
font-size: 60px;
}
#social{
position: relative;
top: 10px;
a {
padding: 5% 5% 5% 5%;
}
}
#fp-menu{
display: block;
color: $menu_black;
}
.pipe{
display: block;
transition: 0.4s;
}
<div id="fp-menu" class="overlay">
<div id="closebtn" style="color: white;">X</div>
<div class="column overlay-content">
<!-- <div class="column"> -->
<div class="col-sm-2 news">
NEWS
</div>
<div class="col-sm-1 pipe">
|
</div>
<div class="col-sm-3 portfolio">
PORTFOLIO
</div>
<div id="social" class="col-sm-6">
<img id="instagram" src='instagram.svg' />
<img id="linkedin" src='linkedin.svg' />
<img id="twitter" src='twitter.svg' />
</div>
</div>
</div>
So the weirdest thing, I've got 1 function that is to trigger under 2 conditions: when the window is resized and when the exit button is clicked.
This relates to an overlay menu that's actually intended for mobile users.
The functions work as they are supposed to, in both cases, when I have the inspection console open in chrome. However, when I close this and return to the normal browser window, the functions cease to execute.
On the mobile it is fine. I have only encountered this problem on the desktop/laptop (as I tried it on different desktops [iMacs] and 2 laptops [Macbooks, but the type of hardware I don't think matters]).
Currently the icons in the "#social" div are not being changed to white, which is what I expect to happen when opened, and when closed, they return to black. They are staying black throughout the execution.
Has anyone ever experienced this before? This is related to a Wordpress platform site. Totally custom built, no themes.
Please let me know if this description helps. If any code is needed, please let me know.
Ps: I thought it was a caching problem, on the terminals or on the server, and I cleared the cache on both but the issue still persists.
function closeOverlayMenu(){//closes the overlay mobile menu
$('#fp-menu').animateCss('slideUp');
$('#fp-menu').css('height', 0);
let overlay_content = document.getElementsByClassName("overlay-content")[0];
let pipe = overlay_content.querySelector(".pipe");
let contact = document.querySelector("#sidebar-leftButton");
let case_studies = document.querySelector("#sidebar-rightButton");
let overlay_contentA = document.querySelectorAll(".overlay a");
for (i = 0; i < overlay_contentA.length; i++) {
overlay_contentA[i].style.color = "black";
}
//changes icons to black on slide up of overlay
document.getElementById('instagram').src="https://s3-eu-west-1.amazonaws.com/mvt-hosted-images/instagram.svg";
document.getElementById('linkedin').src="https://s3-eu-west-1.amazonaws.com/mvt-hosted-images/linkedin.svg";
document.getElementById('twitter').src="https://s3-eu-west-1.amazonaws.com/mvt-hosted-images/twitter.svg";
//restores elements of the original homepage that were hidden for overlay
pipe.style.display="block";
contact.style.display="block";
case_studies.style.display="block";
$('#fp-menu .news').addClass("col-sm-2");
$('#fp-menu .portfolio').addClass("col-sm-3");
$('#fp-menu #social').addClass("col-sm-6");
};
I would expect that the function would trigger without the dev console being active. Please let me know if any further description or information would help.
I want to make a popup that should appear once a button is clicked and disappear once the user clicks outside of the box.
I'm not sure how to make the div disappear when I click outside of it.
var popbox = document.getElementById("popbox");
document.getElementById("linkbox").onclick = function () {
popbox.style.display = "block";
};
???.onclick = function () {
popbox.style.display = "none";
};
Here is the second version which has a transparent overlay as asked by the asker in the comments...
window.onload = function(){
var popup = document.getElementById('popup');
var overlay = document.getElementById('backgroundOverlay');
var openButton = document.getElementById('openOverlay');
document.onclick = function(e){
if(e.target.id == 'backgroundOverlay'){
popup.style.display = 'none';
overlay.style.display = 'none';
}
if(e.target === openButton){
popup.style.display = 'block';
overlay.style.display = 'block';
}
};
};
#backgroundOverlay{
background-color:transparent;
position:fixed;
top:0;
left:0;
right:0;
bottom:0;
display:block;
}
#popup{
background-color:#fff;
border:1px solid #000;
width:80vw;
height:80vh;
position:absolute;
margin-left:10vw;
margin-right:10vw;
margin-top:10vh;
margin-bottom:10vh;
z-index:500;
}
<div id="popup">This is some text.<input type="button" id="theButton" value="This is a button"></div>
<div id="backgroundOverlay"></div>
<input type="button" id="openOverlay" value="open popup">
Here is the first version...
Here is some code. If there is anything else to add, please let me know :)
The event (e) object gives access to information about the event. e.target gives you the element that triggered the event.
window.onload = function(){
var divToHide = document.getElementById('divToHide');
document.onclick = function(e){
if(e.target.id !== 'divToHide'){
//element clicked wasn't the div; hide the div
divToHide.style.display = 'none';
}
};
};
<div id="divToHide">Click outside of this div to hide it.</div>
Here, the idea is to detect click events on the page and set the container’s display to none only when the target of the click isn’t one of the div descendants.
HTML
<div id="container">
<label>Enter your name:</label>
<input type="text">
<button id="submit">Submit</button>
</div>
JS
document.addEventListener('mouseup', function(e) {
var container = document.getElementById('container');
if (!container.contains(e.target)) {
container.style.display = 'none';
}
});
This is code I use to close my side bar when click outside
function openNav() {
document.getElementById("mySidebar").style.width = "100px";
document.getElementById("curtain_menu").style.marginLeft = "100px";
}
function closeNav() {
document.getElementById("mySidebar").style.width = "0";
document.getElementById("curtain_menu").style.marginLeft = "0";
}
document.onclick = function (e) {
if (e.target.id !== 'mySidebar' && e.target.id !== 'btn_frontpage_menu') {
if (e.target.offsetParent && e.target.offsetParent.id !== 'mySidebar')
closeNav()
}
}
.sidebar {
font-family: sans-serif;
height: 50%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
opacity: 0.9;
}
.sidebar a,
.dropdown-btn {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 1vw !important;
color: rgb(195, 195, 195);
display: block;
background: none;
width: 100%;
text-align: left;
cursor: pointer;
outline: none;
transition: 0.3s;
border: none;
}
.dropdown-container a {
color: rgb(174, 174, 174) !important;
}
.sidebar a:hover,
.dropdown-btn:hover,
.dropdown-container a:hover {
color: green !important;
/* background-color: #5c5c5c; */
}
.sidebar .closebtn {
position: absolute;
top: 12px;
font-size: 36px !important;
margin-right: 5px;
text-align: right;
right: 20px;
}
.openbtn {
font-size: 20px !important;
cursor: pointer;
background-color: transparent;
color: black;
padding: 6px 15px;
border: none;
float: left;
}
#main {
position :absolute;
width: 100%;
height: 100%;
left: 100px
}
<div id="mySidebar" class="sidebar" style="width: 100px;">
<a href="javascript:void(0)" class="closebtn"
onclick="closeNav()">×</a>
Home
<div class="dropdown-container">
Job Management
Request
Pending
</div>
</div>
<div id="curtain_menu">
<button id="btn_frontpage_menu" class="openbtn" onclick="openNav()">☰</button>
<div id="datetime"></div>
</div>
<div id="main"> Outside of 'Side Bar' is here
</div>
Here is my Solution.
yourFunc=e=>{
var popbox = document.getElementById("popbox");
if(e.target.id !=="popbox"){
popbox.style.display = "none";
}else{
popbox.style.display = "block";
}
}
document.addEventListener("click",yourFunc)
hope this will work for you
<script>
// Get the element
var modal = document.getElementById('modal');
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
This code is tested and it's working nicely, thank you.
Could be done with onblur event.
// required for focus
divEl.setAttribute('tabindex', '1');
divEl.onblur = event => {
// hide only if blur occurred outside divEl, ignore its children
if (!event.currentTarget.contains(event.relatedTarget)) {
hide();
}
// re-focus, if a child took it
divEl.focus();
};
divEl.focus();
P.S. For IE11 a small hack event.relatedTarget = event.relatedTarget || document.activeElement; could be required.
<div class='icon alk-icon-close'>hidden hire</div>
document.addEventListener('click', function(e) {
var target = e.target.classList.value
if (target == 'icon alk-icon-close') ) {
hidden hire
}
});
plug this in
(function(){
// click outside of element to hide it
let hels = [];
window.hidable = (el, excepter, hider) => {
// hider takes el as the only arg
hels.push([el, excepter, hider]);
return el;
}
window.addEventListener('click', e=>{
for(let i = 0; i < hels.length; i++){
let el = hels[i][0];
let excepter = hels[i][1];
let hider = hels[i][2];
if(!el.contains(e.target) && excepter !== e.target){
hider(el);
}
}
});
})()
unit test
/* excepter is the element to trigger panel show */
// example implementation
window.hidable(panel_el, show_panel_button, el=>el.remove());
// other hiders can be:
el=>el.style.display = 'none';
// depends on your show implementation
el.onmouseleave = function(){
document.body.onclick = function(){
el.style.display = 'none';
document.body.onclick = null;
}
}
Okay, here's a jQuery based solution based on any div clicked within the DOM.
$('div').on('click', function(e){
var parents = $(e.currentTarget).parents();
for (var i = 0; i < parents.length; i++) {
if (parents[i].id === 'divToHide' || e.currentTarget.id === 'divToHide') {
// you are in the popup
};
}
e.stopPropagation();
});
This looks at your current element, as well as any of the parents, and checks if the id matches up. If divToHide is in the parents() list, then you keep the popup open.
*NOTE: This requires wrapping your content within a wrapper div or something similar.