I am trying animating an element which has display property set to null. Objective is to recreate something that bootstrap does in modal.
Further Explanation:
An element which is set to display none on page load but when a user clicks a certain button it shows up with animation (fade in for example). Then when user click on close button or that button again it fades out and its display property is set to none again.
Problem:
When box display property is set to none. And i click on the button. It's display is set to block and adding class "Show" both occur simultaneously and instantaneously so element just shows rather than animating
Here is my Code:
HTML:
<button id="btn">Show / Hide</button>
<div id="box" class="show">
</div>
CSS:
#box {
background-color: aquamarine;
height: 100px;
width: 100px;
opacity: 0;
transition: ease all 0.3s;
}
#box.show {
transition: ease all 0.3s;
opacity: 1;
}
Javascript:
var box = document.querySelector("#box");
var btn = document.querySelector("#btn");
box.style.display = "none"
btn.addEventListener("click", function () {
if(box.style.display == "none") {
return new Promise(function(resolve, reject) {
box.style.display = "block";
resolve();
}).then(function() {
box.classList.add('show');
});
} else if(box.style.display == "block") {
return new Promise(function(resolve, reject) {
box.addEventListener('transitionend', function () {
box.style.display = "none";
})
resolve();
}).then(function() {
box.classList.remove('show');
});
}
});
JSFiddle: https://jsfiddle.net/ptLggbmb/1/
Instead of using Promises you could simply use the transitionend listener and for the fadeIn animation force a layout/reflow before applying the class to the box.
var box = document.querySelector("#box");
var btn = document.querySelector("#btn");
btn.addEventListener("click", function() {
var prevDisplay = box.style.display;
var listener = function() {
box.style.display = "none";
removeListener(listener);
};
if (prevDisplay !== "none") {
addListener(listener);
box.classList.remove('show');
} else {
removeListener(listener);
box.style.display = null;
box.offsetLeft;
box.classList.add('show');
}
function addListener(fn) {
box.addEventListener('transitionend', fn);
}
function removeListener(fn) {
box.removeEventListener('transitionend', fn);
}
});
#box {
background-color: aquamarine;
height: 100px;
width: 100px;
opacity: 0;
transition: ease all 0.3s;
}
#box.show {
transition: ease all 0.3s;
opacity: 1;
}
<button id="btn">Show / Hide</button>
<div id="box" class="show">
</div>
I think you overcomplicated this to the extreme, IMHO. Try this (Pure CSS with a simple JS toggle of classes):
https://jsfiddle.net/ptLggbmb/17/
HTML:
<button id="btn">Show / Hide</button>
<div id="box" class="show">
CSS:
#box {
background-color: aquamarine;
height: 100px;
width: 100px;
opacity: 0;
display: none;
transition: ease all 1s;
}
#box.show {
display: block;
opacity: 1;
}
JS:
var box = document.querySelector("#box");
var btn = document.querySelector("#btn");
btn.addEventListener("click", function () {
box.classList.toggle('show');
});
Related
Please see "box5385.temp.domains/~atelifw5/test/" for reference
I have a div containing a background image that fades on hover. Also, when hovering the background image, a second div image (within the same container) transitions in, positioned on top of the background image.
When you click the top image, it runs JavaScript code that slides in a group of social media icons to the far right. My problem is, when the user hovers over the top image to click it, the background image is no longer faded and it needs to remain faded.
I cannot do this with CSS, because of the order of the divs in the HTML content, will not allow me to do so, and I cannot change the order as the top image will not appear on hover if I change the order. I have tried a number of things with JavaScript and jQuery, but I have been unsuccessful.
Below is my code:
function myFunction() {
var x = document.getElementById("hidden-social");
x.addEventListener("animationend", function(e) {
e.preventDefault();
if (x.style.animationName == "slide-left") {
x.style.display = "none";
}
});
if (x.style.display === "none") {
x.style.display = "block";
x.style.animation = "1s slide-right";
} else {
x.style.animation = "1s slide-left";
}
}
.fading-image {
opacity: 1;
transition: opacity 1s;
}
.fading-image:hover {
opacity: 0.5;
}
.cross-button {
opacity: 0;
transition: opacity 1s;
cursor: pointer;
position: relative;
top: -50px;
left: 325px;
}
.fading-image:hover~.cross-button,
.cross-button:hover {
opacity: 1;
}
.social-icon-2 {
width: 25px;
}
.social-icon-p2 {
width: 15px;
}
#hidden-social-container {
width: 200px;
height: 32px;
position: relative;
top: -80px;
left: 640px;
overflow: hidden;
}
#hidden-social {
width: 145px;
}
#keyframes slide-right {
from {
margin-left: -100%;
}
to {
margin-left: 0%;
}
}
#keyframes slide-left {
from {
margin-left: 0%;
}
to {
margin-left: -100%;
}
}
<div class="ev-fade">
<div class="fading-image"><img src="http://box5385.temp.domains/~atelifw5/wp-
content/uploads/2022/12/RO_PIX_EV_03.png">
</div>
<div class="cross-button" onclick="myFunction()"><img src="http://box5385.temp.domains/~atelifw5/wp-content/uploads/2022/12/cross.thin_.png">
</div>
</div>
<div id="hidden-social-container">
<div id="hidden-social" style="display:none;">
<a href="https://instagram.com" target="blank"><img class="social-icon-
2" src="http://box5385.temp.domains/~atelifw5/wp-content/uploads/2022/12/Instagram_Black.svg">
</a>
<a href="https://www.facebook.com/sharer/sharer.php?
u=http://box5385.temp.domains/~atelifw5/east-village" target="blank"><img class="social-icon-
2" src="http://box5385.temp.domains/~atelifw5/wp-content/uploads/2022/12/Facebook_Black.svg">
</a>
<a href="https://twitter.com/share?url=http://box5385.temp.domains/~atelifw5/east-village/" target="_blank">
<img class="social-icon-2" src="http://box5385.temp.domains/~atelifw5/wp-
content/uploads/2022/12/Facebook_Black.svg"></a>
<a href="https://www.linkedin.com/shareArticle?url=http://box5385.temp.domains/~atelifw5/east-
village" target="blank"><img class="social-icon-
2" src="http://box5385.temp.domains/~atelifw5/wp-content/uploads/2022/12/LinkedIn_Black.svg">
</a>
<a href="https://pinterest.com/pin/create/button/" target="blank"><img class="social-icon-
p2" src="http://box5385.temp.domains/~atelifw5/wp-content/uploads/2022/12/Pinterest_Black.svg">
</a>
</div>
</div>
I changed the classes to Id's. Not that it was necessary, but it just happened along the way while I was working this out. The only thing I did was added the code below to my JavaScript code.
document.getElementById("cross-button").onmouseover = function() {
mouseOver()
};
document.getElementById("cross-button").onmouseout = function() {
mouseOut()
};
function mouseOver() {
document.getElementById("fading-image").style.opacity = "0.5";
}
function mouseOut() {
document.getElementById("fading-image").style.opacity = "1";
}
document.getElementById("fading-image").onmouseover = function() {
mouseOver()
};
document.getElementById("fading-image").onmouseout = function() {
mouseOut()
};
function mouseOver() {
document.getElementById("fading-image").style.opacity = "0.5";
}
function mouseOut() {
document.getElementById("fading-image").style.opacity = "1";
}
This one's a brain cracker for me.
This Event will fire up everytime a transition ends, in our case 5 times because of backgroundColor, borderTopLeftRadius, borderTopRightRadius...
which I don't want, I want this event to fire up only after all transitions have ended. here's a snippet:
function changeStyle() {
const elem = document.getElementById("elem");
const logs = document.getElementById("logs");
elem.style.backgroundColor = "red";
elem.style.borderRadius = "30px";
elem.ontransitionend = () => {
logs.insertAdjacentText("beforeend", "transition ended");
}
}
#elem {
height: 100px;
width: 100px;
color: white;
background-color: blue;
transition: background-color 0.5s, border-radius 0.6s;
}
<div onclick="changeStyle()" id="elem">
click me !
</div>
<span id="logs"></span>
The transitionend event contains a propertyName property, which refers to the property transition that ended. Here, you can examine the event to check which property caused the event to fire. Since the longest transition is the border radius, check if the propertyName is one of the border radiuses:
function changeStyle() {
const elem = document.getElementById("elem");
const logs = document.getElementById("logs");
elem.style.backgroundColor = "red";
elem.style.borderRadius = "30px";
elem.ontransitionend = (e) => {
if (e.propertyName === "border-bottom-right-radius") {
logs.insertAdjacentText("beforeend", "transition ended");
}
}
}
#elem {
height: 100px;
width: 100px;
color: white;
background-color: blue;
transition: background-color 0.5s, border-radius 0.6s;
}
<div onclick="changeStyle()" id="elem">
click me !
</div>
<span id="logs"></span>
My animation function only runs once. I've tried removing and adding classes, as well as running a animationend function to create a retrigger. But still no luck. Any vanilla JS ideas?
CSS:
#element {
width: 10px;
height: 10px;
animation: "";
#keyframes movedown {
100% {
transform: translateY(10px);
}
}
JS:
btn_button.onclick = () => {
element.style.animation = "movedown 10s";
};
HTML:
<div id="element"></div>
You can use setTimeout to set element.style.animation to "". Then, you can add animation name again upon button click.
let btn = document.querySelector("#btn");
btn.onclick = () => {
element.style.animation = "movedown 2s";
setTimeout(() => element.style.animation = "", 2000)
};
#element {
width: 10px;
height: 10px;
background-color: red;
}
#keyframes movedown {
100% {
transform: translateY(50px);
}
}
<div id="element"></div>
<button id="btn">Trigger</button>
I'm trying to show an element for a short amount of time, then hiding it with a CSS transition, on a button click.
Here's the outline of what I did.
elem has a property of opacity: 0.
Fire event when button gets selected.
The events function will add, then remove a class named show to elem.
CSS has the following property: transition: opacity 500ms ease 1000ms;.
#elem.show has a property of opacity: 1.
The problem is, nothing happens when the button gets clicked on. How can I make element get shown, without a transition effect, then, after 1s close with a transition?
JSFiddle
var btn = document.getElementById('btn');
var elem = document.getElementById('elem');
btn.addEventListener('click', function() {
elem.classList.add('show');
elem.classList.remove('show');
});
#elem {
background-color: orange;
width: 100px;
height: 100px;
opacity: 0;
transition: opacity 500ms ease 1000ms;
}
#elem.show {
opacity: 1;
transition: none;
}
<button id="btn">Press Me</button>
<div id="elem"></div>
Using setTimeout is not tidy - it is better to listen to the animation end event and remove the show class. I have also used animation to show and hide the element successively - see demo below:
var btn = document.getElementById('btn');
var elem = document.getElementById('elem');
btn.addEventListener('click', function() {
elem.classList.remove('show');
// this force-restarts the CSS animation
void elem.offsetWidth;
elem.classList.add('show');
});
elem.addEventListener("animationend", function(){
elem.classList.remove('show');
}, false);
#elem {
background-color: orange;
width: 100px;
height: 100px;
opacity: 0;
}
#elem.show {
animation: anime 1s 1;
}
#keyframes anime {
0% {
opacity: 1;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<button id="btn">Press Me</button>
<div id="elem"></div>
Update
Listening to the animation-end event do not seem necessary actually - it works properly even without it. The gist here is the use of void elem.offsetWidth to forcefully restart the animation:
var btn = document.getElementById('btn');
var elem = document.getElementById('elem');
btn.addEventListener('click', function() {
elem.classList.remove('show');
// this force-restarts the CSS animation
void elem.offsetWidth;
elem.classList.add('show');
});
#elem {
background-color: orange;
width: 100px;
height: 100px;
opacity: 0;
}
#elem.show {
animation: anime 1s 1;
}
#keyframes anime {
0% {
opacity: 1;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<button id="btn">Press Me</button>
<div id="elem"></div>
just do this :
setTimeout(function() { elem.classList.remove('show'); }, 1000);
instead of writing :
elem.classList.remove('show');
To handle repeated clicks, do this ::
var btn = document.getElementById('btn');
var elem = document.getElementById('elem');
var timeOutFunc;
btn.addEventListener('click', function() {
elem.classList.add('show');
clearTimeout(timeOutFunc);
timeOutFunc = setTimeout(function() {elem.classList.remove('show') } , 1000);
});
This borrows from other answers, and addresses the multiple press "issue"
var btn = document.getElementById('btn');
var elem = document.getElementById('elem');
btn.addEventListener('click', (function() {
var timer = null;
return function() {
elem.classList.add('show');
if (timer) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(e => elem.classList.remove('show'), 1000);
};
})());
#elem {
background-color: orange;
width: 100px;
height: 100px;
opacity: 0;
transition: opacity 500ms ease 500ms;
}
#elem.show {
opacity: 1;
transition: none;
}
<button id="btn">Press Me</button>
<div id="elem"></div>
Try with this...i Hope its resolved your prblm
https://jsfiddle.net/b3en368p/5/
var btn = document.getElementById('btn');
var elem = document.getElementById('elem');
btn.addEventListener('click', function() {
elem.classList.add('show');
setTimeout(function(text){
elem.classList.remove('show');
}, 1000);
});
Add css
#elem {
background-color: orange;
width: 100px;
height: 100px;
display: none;
}
#elem.show {
display: block;
}
Your listener should be like this-
btn.addEventListener('click', function() {
elem.classList.add('show');
setTimeout(function(){
elem.classList.remove('show');
}, 1000);
});
With the following line of code:
document.getElementById("myDiv").innerHTML=txt;
Is it possible to add the .fadeIn("slow" ) function? I would like the new text to fade in.
Do it with js+CSS.
With a CSS transition it will fade in.
You need to have the font-color set to background-color.
First change content,
then change color to normal font color.
Your js:
document.getElementById("myDiv").innerHTML=txt;
document.getElementById("myDiv").style.color = "#333333";
Your CSS:
#myDiv {
color: #ffffff;
transition: color 2s ease 0s;
}
Ended up just doing this:
$("div.col-lg-6").replaceWith(function() {
return $(txt).hide().fadeIn(1000);});
A bit of a hack, but you could do it like this: http://codepen.io/zvona/pen/LVxxjM
Where we use CSS transitions for the purpose.
<button class='add'>Add text</button>
<button class='clear'>Clear text</button>
<div id="myDiv"></div>
and:
#myDiv {
opacity: 0;
transition: opacity 1000ms;
}
#myDiv.show {
opacity: 1;
}
and:
var myDiv = document.querySelector("#myDiv");
document.querySelector(".add").addEventListener('click', function() {
myDiv.textContent = "Fade magic";
myDiv.classList.add('show');
}, false);
document.querySelector(".clear").addEventListener('click', function() {
myDiv.classList.remove('show');
}, false);
In CSS
#mydiv {
opacity: 0;
transition: opacity 2s;
}
In JS
document.getElementById("myDiv").style.opacity= "1";
Try not to worry about fading in/out the innerHTML property. Instead, wrap the innerHTML in a span tag (or, alternatively, a div tag), and then simply fade that element in and out.
Here it is with a 1,000 millisecond delay:
const fadetime = 1000;
function fadeInElement(element) {
element.style.removeProperty('display');
setTimeout(function() {
element.classList.remove('fade');
}, 10);
return true;
}
function fadeOutElement(element) {
element.classList.add('fade');
setTimeout(function() {
element.style.display = 'none';
}, fadetime);
return true;
}
var buttondisplay = false;
document.getElementById('button').addEventListener('click', function(ev) {
if(buttondisplay) {
fadeOutElement(document.getElementById('button-text-2'));
setTimeout(function() {
fadeInElement(document.getElementById('button-text-1'));
}, fadetime);
} else {
fadeOutElement(document.getElementById('button-text-1'));
setTimeout(function() {
fadeInElement(document.getElementById('button-text-2'));
}, fadetime);
}
buttondisplay = !buttondisplay;
});
.fadeable {
opacity: 1;
transition: opacity 1s;
}
.fade {
opacity: 0 !important;
}
<button id="button">
<span id="button-text-1" class="fadeable">First Text</span>
<span id="button-text-2" class="fadeable fade" style="display:none;">Second text!</span>
</button>