How to make image transition smoothly with toggle button - javascript

I used transition to make the change smooth and it is working, but for the image I couldn't setup well. How can I fix this?
I tried this:
var lightsOff = document.querySelector("#lights-off");
var lightsOn = document.querySelector("#lights-on");
lightsOff.style.display = "block";
lightsOn.style.display = "none";
And this:
var lightsOff = document.querySelector("#lights-off");
var lightsOn = document.querySelector("#lights-on");
lightsOff.style.display = "none";
lightsOn.style.display = "block";
Here is the full code:
function myFunction() {
var elements = document.querySelectorAll(".one, .three, .five");
elements.forEach(function(element) {
element.classList.toggle("dark-mode");
if (element.classList.contains("dark-mode")) {
if (element.classList.contains("one")) {
var logoElement = element.querySelector('.logo');
var h2Element = element.querySelector('h2');
var sloganElement = element.querySelector('.slogan');
logoElement.style.setProperty('color', 'white');
sloganElement.style.setProperty('color', 'white');
h2Element.style.setProperty('color', 'white');
} else if (element.classList.contains("three")) {
var textThreeOne = element.querySelector('.text-threeone');
var textThreeTwo = element.querySelector('.text-threetwo');
var p = element.querySelector('.text-threetwo + p');
textThreeOne.style.setProperty('color', 'white');
textThreeTwo.style.setProperty('color', 'white');
p.style.setProperty('color', 'white');
var lightsOff = document.querySelector("#lights-off");
var lightsOn = document.querySelector("#lights-on");
lightsOff.style.display = "block";
lightsOn.style.display = "none";
var blackmoon = document.querySelector(".moon");
blackmoon.style.display = "block";
} else if (element.classList.contains("five")) {
var inputs = element.querySelectorAll('input');
var textarea = element.querySelector('textarea');
var submitBtn = element.querySelector('input[type="submit"]');
inputs.forEach(input => {
input.style.setProperty('background-color', '#1f1f1f');
input.style.setProperty('color', '#ffffff');
});
textarea.style.setProperty('background-color', '#1f1f1f');
textarea.style.setProperty('color', '#ffffff');
submitBtn.style.setProperty('background-color', '#1f1f1f');
// Toevoegen muisover kleur
submitBtn.style.setProperty('transition', 'background-color 0.2s');
submitBtn.addEventListener("mouseover", function() {
submitBtn.style.setProperty('background-color', '#101010');
});
submitBtn.addEventListener("mouseout", function() {
submitBtn.style.setProperty('background-color', '#1f1f1f');
});
var contact = element.querySelector('#contact');
var pOne = element.querySelector('.five>p+p');
var pTwo = element.querySelector('.five>p+p+p');
contact.style.setProperty('color', 'white');
pOne.style.setProperty('color', 'white');
pTwo.style.setProperty('color', 'white');
} else {
element.style.setProperty('color', 'white');
}
} else {
if (element.classList.contains("one")) {
var logoElement = element.querySelector('.logo');
logoElement.style.setProperty('color', '#353535');
var sloganElement = element.querySelector('.slogan');
sloganElement.style.setProperty('color', '#353535');
var sloganElement = element.querySelector('h2');
sloganElement.style.setProperty('color', '#353535');
var blackmoon = document.querySelector(".moon");
blackmoon.style.display = "none";
} else if (element.classList.contains("three")) {
var textThreeOne = element.querySelector('.text-threeone');
var textThreeTwo = element.querySelector('.text-threetwo');
var p = element.querySelector('.text-threetwo + p');
var lightsOff = document.querySelector("#lights-off");
var lightsOn = document.querySelector("#lights-on");
lightsOff.style.display = "none";
lightsOn.style.display = "block";
p.style.setProperty('color', '#353535');
textThreeOne.style.setProperty('color', '#353535');
textThreeTwo.style.setProperty('color', '#353535');
} else if (element.classList.contains("five")) {
var inputs = element.querySelectorAll('input');
var textarea = element.querySelector('textarea');
var submitBtn = element.querySelector('input[type="submit"]');
inputs.forEach(input => {
input.style.setProperty('background-color', '#efefef');
input.style.setProperty('color', 'black');
});
textarea.style.setProperty('background-color', '#efefef');
textarea.style.setProperty('color', 'black');
submitBtn.style.setProperty('background-color', '#437bff');
submitBtn.style.setProperty('color', 'white');
// Toevoegen muisover kleur
submitBtn.style.setProperty('transition', 'background-color 0.2s');
submitBtn.addEventListener("mouseover", function() {
submitBtn.style.setProperty('background-color', '#133edb');
});
submitBtn.addEventListener("mouseout", function() {
submitBtn.style.setProperty('background-color', '#437bff');
});
var contact = element.querySelector('#contact');
var pOne = element.querySelector('.five>p+p');
var pTwo = element.querySelector('.five>p+p+p');
contact.style.setProperty('color', '#353535');
pOne.style.setProperty('color', '#353535');
pTwo.style.setProperty('color', '#353535');
}
}
});
}
.one,
.three,
.five {
transition: 1500ms;
}
<div>
<button class="darkmodebtn" onclick="myFunction()"></button>
<img id="lights-off" src="../images/darkmode.png" style="display: none;">
<img id="lights-on" src="../images/ABC.png">
</div>

document.querySelector('.light-on1').addEventListener('click', function() {
const el = document.querySelector('.container1 img');
toggle_light_on_display(el);
})
document.querySelector('.light-off1').addEventListener('click', function() {
const el = document.querySelector('.container1 img');
toggle_light_off_display(el);
})
function toggle_light_on_display(el) {
el.style.opacity = '0';
el.style.display = 'block';
const to = setTimeout(function() {
el.style.opacity = '1';
clearTimeout(to); // lot better to clear timeout when no more use
}, 200) // this little delay is for the display block to finish
}
function toggle_light_off_display(el) {
el.style.opacity = '0';
const to = setTimeout(function() {
el.style.display = 'none';
clearTimeout(to); // lot better to clear timeout when no more use
}, 500) // this delay is the delay of the transition
}
document.querySelector('.light-on2').addEventListener('click', function() {
const el = document.querySelector('.container2 img');
toggle_light_on_visibility(el);
})
document.querySelector('.light-off2').addEventListener('click', function() {
const el = document.querySelector('.container2 img');
toggle_light_off_visibility(el);
})
function toggle_light_on_visibility(el) {
el.style.opacity = '0';
el.style.visibility = 'visible';
const to = setTimeout(function() {
el.style.opacity = '1';
clearTimeout(to); // lot better to clear timeout when no more use
}, 200) // this little delay is for the visibility visible to finish
}
function toggle_light_off_visibility(el) {
el.style.opacity = '0';
const to = setTimeout(function() {
el.style.visibility = 'hidden';
clearTimeout(to); // lot better to clear timeout when no more use
}, 500) // this delay is the delay of the transition
}
.container1 img {
display: none;
transition: 500ms ease-in all;
}
.container2 img {
visibility: hidden;
transition: 500ms ease-in all;
}
<button class="light-on1">light-on display</button>
<button class="light-off1">light-off display</button>
<div class="container1">
<img src="https://picsum.photos/id/20/800/600" alt="">
</div>
<button class="light-on2">light-on visibility</button>
<button class="light-off2">light-off visibility</button>
<div class="container2">
<img src="https://picsum.photos/id/30/800/600" alt="">
</div>
So here you have the 2 versions, display and visibility.
To see the real usage difference, in the HTML, put the block of container 2 and buttons 2 before the 1. With visibility the space is preserve.
For the code, I left on and off as 2 functions, can grouped in 1 as a toggle function. Detection could be done on style opacity in first case and visibility on second.
You can play with the delay. Note that there is a little delay to put when changing display to on and visibility to visible. Browser need little time to render that.
You can play with transition on image and its delay. If you change transition timing, change the off delay accordingly.
You can adapt this for your code easily.

ok new snippet, I mixed the 2 functions in 1 using your html
function myFunction() {
const lightsOff = document.querySelector("#lights-off");
const lightsOn = document.querySelector("#lights-on");
if (lightsOff.style.display === 'none') {
toggle_light_display('off');
} else {
toggle_light_display('on');
}
}
function toggle_light_display(test) {
let el1, el2;
if (test === 'off') {
el1 = document.querySelector("#lights-on");
el2 = document.querySelector("#lights-off");
} else {
el1 = document.querySelector("#lights-off");
el2 = document.querySelector("#lights-on");
}
el1.style.opacity = '0';
let to = setTimeout(function() {
el1.style.display = 'none';
clearTimeout(to);
el2.style.opacity = '0';
el2.style.display = 'block';
to = setTimeout(function() {
el2.style.opacity = '1';
clearTimeout(to);
}, 200)
}, 500)
}
img {
transition: 500ms ease-in all;
}
<div>
<button class="darkmodebtn" onclick="myFunction()">switch</button>
</div>
<div>
<img id="lights-off" src="https://picsum.photos/id/20/800/600" alt="" style="display: none;">
<img id="lights-on" src="https://picsum.photos/id/30/800/600" alt="">
</div>

Related

How can I get my JavaScript popup to show only once per session?

I've created a JavaScript code for a website popup. I need the popup to only appear when the user scrolls back to the top of the page and only appear once per session.
I used the function below to tell the popup to appear when the user scrolls back to the top:
window.addEventListener('scroll', function() {
if (window.pageYOffset === 0) {
It works, however the popup now appears every time the user scrolls to the top and not only once per session like I had coded it to.
I want to achieve this using only JavaScript
Here is a link where you can see it in action >> https://digitalcloud.co.za/kiron/
This is the full script
<script>
// Check if the popup has already been shown during the current session
if (!sessionStorage.getItem('popupShown')) {
window.addEventListener('scroll', function() {
if (window.pageYOffset === 0) {
var popup = document.createElement("div");
popup.style.position = "fixed";
popup.style.top = "0";
popup.style.left = "0";
popup.style.zIndex = "999";
popup.style.backgroundColor = "rgba(0, 0, 0, 0.5)";
popup.style.width = "100vw";
popup.style.height = "100vh";
popup.style.display = "flex";
popup.style.alignItems = "center";
popup.style.justifyContent = "center";
var innerPopup = document.createElement("div");
innerPopup.style.backgroundColor = "black";
innerPopup.style.display = "flex";
innerPopup.style.flexDirection = "column";
innerPopup.style.alignItems = "center";
innerPopup.style.justifyContent = "center";
innerPopup.style.padding = "40px";
innerPopup.style.margin = "35px";
innerPopup.style.borderRadius = "25px";
var img = document.createElement("img");
img.src = "https://digitalcloud.co.za/wp-content/uploads/2023/01/kerridge_pop_up_illustration.png ";
img.alt = "Find out about Kerridge’s core solution ";
img.style.width = "25%";
img.style.cursor = "pointer";
innerPopup.appendChild(img);
var text = document.createElement("p");
text.innerHTML = "Interested to find out more about our core solution?";
text.style.color = "white";
text.style.marginTop = "50px";
text.style.textAlign = "center";
text.style.fontSize = "20px";
innerPopup.appendChild(text);
var button = document.createElement("button");
button.innerHTML = "Book a free demo today";
button.style.backgroundColor = "#E8017B";
button.style.color = "white";
button.style.fontSize = "20px";
button.style.padding = "15px";
button.style.borderRadius = "50px"
button.style.border = "none"
button.onclick = function() {
location.href = "https://digitalcloud.co.za/ ";
}
innerPopup.appendChild(button);
var secondText = document.createElement("p");
secondText.innerHTML = "Stay up to date with the latest Kerridge product updates and existing announcements";
secondText.style.color = "white";
secondText.style.marginTop = "50px";
secondText.style.textAlign = "center";
secondText.style.fontSize = "20px";
innerPopup.appendChild(secondText);
var secondButton = document.createElement("button");
secondButton.innerHTML = "Sign up to our Newsletter";
secondButton.style.color = "#E8017B";
secondButton.style.background = "transparent";
secondButton.style.border = "none";
secondButton.style.fontSize = "20px";
secondButton.onclick = function() {
location.href = "https://digitalcloud.co.za/ ";
}
innerPopup.appendChild(secondButton);
var closeBtn = document.createElement("div");
closeBtn.style.position = "absolute";
closeBtn.style.top = "50px";
closeBtn.style.right = "50px";
closeBtn.style.cursor = "pointer";
closeBtn.style.width = "60px";
closeBtn.style.height = "60px";
closeBtn.style.borderRadius = "50%";
closeBtn.style.backgroundColor = "#E8017B";
closeBtn.style.display = "flex";
closeBtn.style.alignItems = "center";
closeBtn.style.justifyContent = "center";
closeBtn.setAttribute("tabindex", "0");
closeBtn.setAttribute("role", "button");
closeBtn.setAttribute("aria-label", "Close");
closeBtn.addEventListener("click", function() {
// Add logic to close something here
popup.remove();
});
closeBtn.addEventListener("keydown", function(event) {
if (event.key === "Enter" || event.key === " ") {
// Add logic to close something here
popup.remove();
}
});
var closeX = document.createElement("div");
closeX.innerHTML = "X";
closeX.style.color = "white";
closeX.style.fontWeight = "bold";
closeBtn.appendChild(closeX);
closeBtn.onclick = function() {
popup.remove();
}
innerPopup.appendChild(closeBtn);
popup.appendChild(innerPopup);
document.body.appendChild(popup);
// Set a value in sessionStorage indicating that the popup has been shown
sessionStorage.setItem('popupShown', 'true');
};
}
</script>
I used a function to ensure the popup only appears when the user scrolls to the top but I need it to only appear once per session.
Unbind the event after it is shown to the user so it is not called again
const scrollCode = () {
if (window.pageYOffset === 0) {
sessionStorage.setItem('popupShown', '1');
window.removeEventListener('scroll', scrollCode);
/* your pop up code */
}
};
if (!sessionStorage.getItem('popupShown') {
window.addEventListener('scroll', scrollCode)
}
Create a variable somewhere before your function, for example index = 0, then, within your scroll function, add 1 to the index > index += 1, and then, within your function, add if statement, that will check whether the index is 0, which will mean that it has not yet been scrolled, and if it is, then it has been scrolled and will not proceed to the rest of the function.
let index = 0;
window.addEventListener('scroll', function() {
if (window.pageYOffset === 0) {
index += 1;
if (index <= 0) {
*your code*
}
}
}

I moved my script from HTML to external js. But this part doesn't work unless I put it on top of js file, why?

I use this part to show and hide (to top btn) in HTML.
// <!-- show (to top) btn -->
window.onscroll = function () {
scroll();
};
function scroll() {
if (document.body.scrollTop > 150 || document.documentElement.scrollTop > 150) {
document.getElementById("toTopBtn-container").style.top = "96vh";
} else {
document.getElementById("toTopBtn-container").style.top = "110vh";
}
}
It was at the bottom and works normally. After I move it to an external js file and put it as it was in the HTML file at the bottom of the script, it doesn't work. But if I put it on top of the external js file, it works normally.
Help me understand why it is behaving like that, please.
Here is the rest of the js script
var menu = document.getElementById("mobile-menu");
var menuImg = document.getElementById("menuImg");
var closeMenuImg = document.getElementById("closeMenuImg");
menu.style.display = "block";
menu.style.marginLeft = "1000px";
menu.style.opacity = "1";
menuImg.style.display = "block";
closeMenuImg.style.display = "none";
function clickMenu() {
if (menuImg.style.display == "block") {
// btn animation
menuImg.style.transform = "rotateZ(180deg)";
menuImg.style.transition = "0.3s";
// menu animation
menu.style.marginLeft = "0";
menu.style.opacity = "1";
menu.style.transition = "0.5s";
setTimeout(() => {
menuImg.style.display = "none";
closeMenuImg.style.display = "block";
menu.style.display = "block";
// untoggle animation
menuImg.style.transform = "rotateY(0deg)";
menuImg.style.width = "80px";
menuImg.style.transition = "0.3s";
}, 200);
} else {
// btn animation
closeMenuImg.style.transform = "rotateZ(-180deg)";
closeMenuImg.style.transition = "0.3s";
// menu animation
menu.style.marginLeft = "1000px";
menu.style.transition = "0.4s";
setTimeout(() => {
menuImg.style.display = "block";
closeMenuImg.style.display = "none";
// untoggle animation
closeMenuImg.style.transform = "rotateY(0deg)";
closeMenuImg.style.width = "80px";
closeMenuImg.style.transition = "0.3s";
}, 200);
}
}
var mobileWorkBtn = document.getElementById(mobile - work - btn);
var mobileContactBtn = document.getElementById(mobile - contact - btn);
function clickMobileMenuItem() {
// btn animation
closeMenuImg.style.transform = "rotateZ(-180deg)";
closeMenuImg.style.transition = "0.3s";
// menu animation
menu.style.marginLeft = "1000px";
menu.style.transition = "0.4s";
setTimeout(() => {
menuImg.style.display = "block";
closeMenuImg.style.display = "none";
closeMenuImg.style.transform = "rotateY(0deg)";
closeMenuImg.style.width = "80px";
closeMenuImg.style.transition = "0.3s";
}, 200);
}
var mobileWorkBtn = document.getElementById(mobile - work - btn);
var mobileContactBtn = document.getElementById(mobile - contact - btn);
is probably meant to be:
var mobileWorkBtn = document.getElementById("mobile-work-btn");
var mobileContactBtn = document.getElementById("mobile-contact-btn");
never mind guys,
after I removed the two variables,
var mobileWorkBtn = document.getElementById(mobile - work - btn);
var mobileContactBtn = document.getElementById(mobile - contact - btn);
and restart the browser and editor, suddenly it works on the bottom as it was in HTML.
the annoying part is, I still don't know why it didn't work first time !?

dropdown menu animation with JS

There is my menu without animation:
https://jsfiddle.net/sj0pycb7/5/
When I try add a code like that it doesn't work correct.
;(function(){
var height = 1;
var intervalID;
var get = document.getElementsByClassName('dropdown');
var set = document.querySelector('.menu .dropdown ul');
get[0].addEventListener('mouseover', function(){
startAnim();
}, false);
get[0].addEventListener('mouseout', function(){
stopAnim();
set.style.display = 'none';
}, false);
function startAnim(){
intervalID = setInterval(increaseHeight, 10);
set.style.overflow = 'hidden';
}
function stopAnim(){
set.removeAttribute('style');
set.style.display = 'none';
clearInterval(intervalID);
height = 1;
}
function increaseHeight(){
if(height){
height += 5;
height++;
set.style.height = height + 'px';
set.style.display = 'inline-block';
}
if(height>210){
height = 0;
clearInterval(intervalID);
set.removeAttribute('style');
set.style.display = 'inline-block';
}
}
})();
Problem is that event 'mouseout' executes(display:none) when I hovering between dropdown menu anchors. Removing margin and borders doesn't help.
Problem is solved with jQuery:
https://jsfiddle.net/sj0pycb7/6/
;(function(){
$(document).ready(function() {
$( '.dropdown' ).hover(
function(){
$(this).children('.submenu').slideDown(200);
},
function(){
$(this).children('.submenu').slideUp(200);
}
);
});
})();

Hide element with a delay

In this case the element hides at ones. Can't understand why it's not show a "P" tag at first and then slowly hides it. Please, help me to fix a problem.
var step = 0.1;
var delay = 90000;
var displayMe = function() {
if (element.style.opacity < 1) {
element.style.opacity += step;
setTimeout('displayMe()', delay);
}
}
var hideMe = function() {
var elem = document.getElementById('regform');
if (elem.style.opacity >= 0) {
elem.style.opacity -= step;
setTimeout('hideMe ()', delay);
}
}
hideMe();
<p id="regform">aaaaaaaaaaaaaaaaa</p>
Element.style.prop will read only inline styles. Define style='opacity:1' for <p> element.
var step = 0.1;
var delay = 1000;
var displayMe = function() {
if (element.style.opacity < 1) {
element.style.opacity += step;
setTimeout(displayMe, delay);
}
}
var hideMe = function() {
var elem = document.getElementById('regform');
if (elem.style.opacity >= 0) {
elem.style.opacity -= step;
setTimeout(hideMe, delay);
}
}
hideMe();
<p id="regform" style='opacity:1'>aaaaaaaaaaaaaaaaa</p>
Try
document.getElementById('regform').style.opacity=1;
var hideMe = function()
{
var elem = document.getElementById('regform');
if(elem.style.opacity>0)
{
elem.style.opacity-= step;
setTimeout(hideMe, delay);
}
}
hideMe();
Fiddle
Try it with jquery:
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$(document).ready( function() {
$('#regform').delay(1000).fadeOut(2000);
});
</script>
<p id="regform" style='opacity:1'>aaaaaaaaaaaaaaaaa</p>
Documentation .fadeOut()

streaming, wrapping Javascript Div

Is there a way to wrap this div so that content that goes off the screen on the right immediately appears on the left?
Basically, I just need it to loop.
HTML
<div id="contents">
<div id="join">
</div>
</div>
JS
var currentPos = 0;
var intervalHandle;
function beginAnimate() {
document.getElementById("join").style.position = "absolute";
document.getElementById("join").style.left = "0px";
// document.getElementById("join").style.top = "100px";
// cause the animateBox function to be called
intervalHandle = setInterval(animateBox,30);
}
function animateBox() {
//set new position
currentPos+=5;
document.getElementById("join").style.left = currentPos + "px";
//
if ( currentPos > innerWidth) {
//clear interval
clearInterval(intervalHandle);
currentPos = 0;
//reset custom inline style
beginAnimate();
//document.getElementById("join").style.top = "";
}
}
function preparePage() {
document.getElementById("join").onclick = function() {
if ( document.getElementById("join").className == "callOut") {
document.getElementById("join").className = "";
} else {
document.getElementById("join").className = "callOut";
}
};
}
window.onload = function() {
preparePage();
beginAnimate();
animateBox();
}

Categories

Resources