Unset element visibility, change innerHTML, and transisition back - javascript

I have an element on my HTML page that I want to give dynamic content, and I want inserted HTML to transition from 0% to 100% opacity.
HTML
<div id="content"></div>
CSS
#content {
opacity: 1;
transition: opacity .5s ease-out;
-moz-transition: opacity .5s ease-out;
-webkit-transition: opacity .5s ease-out;
}
#content.hide {
opacity: 0;
}
JavaScript
function setContent(html) {
var content = document.getElementById("content");
//Set hide class
content.className += " hide";
//Set HTML
content.innerHTML = html;
//Unset hide class
content.className = content.className.replace(/(?:^|\s)hide(?!\S)/g, '');
}
Note that setContent() sets and then unsets the hide class. However, it seems that the browser (Chrome at least) does not invalidate content element until after it return from the function, so the element does not get the chance to transistion. How can I make sure that the animation plays?
EDIT: To be clear, setContent() is called after the DOM is loaded. Imagine an app that clears and repopulates the screen when some action occurs.

Can you be more clear as what the context of this is?
Also where are you calling the function? Is the place where you are calling the function inside a DOM ready function?
In jQuery it would be something like this:
$(document).ready(function(){
//call the function inside here.
});

What about using animations?
#content {
padding-left: 32px;
padding-right: 32px;
animation: fadein 0.5s;
-moz-animation: fadein 0.5s;
-webkit-animation: fadein 0.5s;
}
#keyframes fadein {
from {
opacity:0;
}
to {
opacity:1;
}
}
#-moz-keyframes fadein {
from {
opacity:0;
}
to {
opacity:1;
}
}
#-webkit-keyframes fadein {
from {
opacity:0;
}
to {
opacity:1;
}
}

Related

Changing max-height back to zero as transition or animation

So I have got an animation on an object (<div>).
#keyframes fade-in-left {
0% {
max-height: 0px;
}
100% {
max-height: 200px;
}
This animation obviously happens when the object is being created. What I need now is an animation or transition that shrinks my object back down to max-height: 0px;.
Giving the property max-height an transition and then changing the value of it in js to 0px does nothing.
Also creating a reversed animation and then repolacing the original
object with a clone and this animation does not bring the object down
to 0px.
(Please keep in mind that I am not intersted in changing the scale or other transform properties)
Thanks for your suggestions!
More details:
My <div> object:
#keyframes fade-in-left {
0% {
max-height: 0px;
}
100% {
max-height: 200px;
}
}
.law-list .law-item {
-webkit-transition: max-height .9s linear;
-moz-transition: max-height .9s linear;
-ms-transition: max-height .9s linear;
-o-transition: max-height .9s linear;
transition: max-height .9s linear;
}
.fade-in {
-webkit-animation-duration: .9s;
animation-duration: .9s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-name: fade-in-left;
animation-name: fade-in-left;
}
I create my html content in js and the html elements looks like this:
<div class='law-item fade-in' id='law_0'>Law Nr.1</div>
<div class='law-item fade-in' id='law_1'>Law Nr.2</div>
So when an element is created, the max-height animation plays.
When I want to delete an object, I want the situation stated above to occur: a fade out animation and then an deletion.
I handel his in a js function:
function removeLaw(id) {
document.getElementById("law_" + id).style.maxHeight = "0px";
setTimeout(function() {
document.getElementById("law_" + id).parentElement.removeChild(document.getElementById("law_" + id));
}, 900);
}
As stated it should fade out to 0 max-height. But all it does it stay at the current max-height and then after max-height get deleted.
There is always more than one way to do something. Since you are using an animation to set the height, it is best to use an animation to remove the height as well. Think of the animation ending at 100%. At this point, your max-height is set. Even though you have a transition set on the element, the animation is preventing the transition from firing as it should. The animation event is still firing even though it is at 100%. You could set an event listener on the animationend event from the beginning and pause the animation. I haven't tried this, but it may work.
What I found in your case is to create a fade-out class and a fade-out animation. I removed all references to transition from your css since I used animations. I suppose you could go the other way and use only transitions instead of animations, but mixing them is the problem you have been having.
I created a basic click event listener on each law-item and changed the class on the item prior to removing when the new animation ended.
function removeLaw(id) {
var el = document.getElementById(id);
el.classList.remove('fade-in');
el.classList.add('fade-out');
el.addEventListener('animationend', function(e) {
el.remove();
})
}
var lawItems = document.querySelectorAll('.law-item');
lawItems.forEach(function(lawItem){
this.addEventListener('click', function(e) {
removeLaw(e.target.id)
})
})
#keyframes fade-in-left {
0% {
max-height: 0px;
}
100% {
max-height: 200px;
}
}
#keyframes fade-out-left {
0% {
max-height: 200px;
}
100% {
max-height: 0px;
}
}
.law-list .law-item {
height: 200px;
}
.fade-in {
-webkit-animation-duration: 900ms;
animation-duration: 900ms;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-name: fade-in-left;
animation-name: fade-in-left;
}
.fade-out {
-webkit-animation-duration: 900ms;
animation-duration: 900ms;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-name: fade-out-left;
animation-name: fade-out-left;
}
<div class='law-list'>
<div class='law-item fade-in' id='law_0'>Law Nr.1</div>
<div class='law-item fade-in' id='law_1'>Law Nr.2</div>
</div>

How can I trigger a keyframe when the user scrolls to a certain part of a page

is it possible to detect where a user scrolls on a page to trigger a keyframe using pure javascript ?
.animations {
opacity: 0;
animation: animations-keyframes 2s ease forwards;
-webkit-animation: animations-keyframes 2s ease forwards;
animation-delay: 0.5s;
-webkit-animation-delay: 0.5s;
}
#keyframes animations-keyframes {
to {
opacity: 1;
}
}
#-webkit-keyframes animations-keyframes {
to {
opacity: 1;
}
}
I want javascript to trigger this event when the user gets to a certain part of a page for example a content section. I don't know where to start
Using javascript, you could add the class animations to an element on mouseenter event and remove the class on mouseleave. Since you didn't mention jQuery, I will use simple JS, but I recommend using jQuery if you plan on doing a bunch of DOM manipulation since it is easier to maintain.
EXAMPLE:
http://jsfiddle.net/dirtyd77/z6xmuwse/2/
JAVASCRIPT:
var el = document.getElementById("animation");
el.onmouseenter = function (){
this.classList.add("animations");
};
el.onmouseleave = function (){
this.classList.remove("animations");
};
However, you can also accomplish this using just CSS and the pseudo :hover.
EXAMPLE:
http://jsfiddle.net/dirtyd77/z6xmuwse/3/
CSS:
.animations:hover {
opacity: 0;
animation: animations-keyframes 2s ease forwards;
-webkit-animation: animations-keyframes 2s ease forwards;
animation-delay: 0.5s;
-webkit-animation-delay: 0.5s;
}
#keyframes animations-keyframes {
to {
opacity: 1;
}
}
#-webkit-keyframes animations-keyframes {
to {
opacity: 1;
}
}
Hope this helps and let me know if you have any questions!
Waypoints can be used to trigger events when scrolling to certain parts of a page.
http://imakewebthings.com/waypoints/
In simple terms, event listeners are created for scroll events - The distance scrolled down the page and distance of the element from the top of the page are compared. Events are triggered if the user has scrolled beyond the element ( distance scrolled > distance of element from top of page )

fade in then fade out after some time by using css-transitions

I'd like to fade in, wait some time, then fade out an element of homepage using jQuery's addClass and removeClass
This JS-code fades in the div but doesn't fade it out. I'm using jQuery 2.1.3
if ($("#save-success").hasClass("fadeout")){
$("#save-success").removeClass("fadeout").addClass("fadein", function() {
$(this).delay(2000).removeClass("fadein").addClass("fadeout");
})
}
I've got this CSS:
.fadein, .fadeout {
opacity: 0;
transition: opacity 0.4s ease-in-out;
}
.fadein {
opacity: 1;
}
this HTML:
<div id="save-success" class="fadeout">
Successfully saved
</div>
addclass() method doesn't take callback as argument. Try this instead:
if ($("#save-success").hasClass("fadeout")) {
$("#save-success").removeClass("fadeout").addClass("fadein");
setTimeout(function () {
$('#save-success').removeClass("fadein").addClass("fadeout");
}, 2000);
}
jsfiddle: http://jsfiddle.net/gwugyo4v/
You should change your CSS
.fadeout {
opacity: 0;
transition: opacity 0.4s ease-in-out;
}
.fadein {
opacity: 1;
transition: opacity 0.4s ease-in-out;
}
Without Classes
if ($("#save-success").hasClass("fadeout")){
$("#save-success").fadeIn(400, function() {
$(this).delay(2000).fadeOut(400);
});
}

show div and execute CSS animation in separate div on "li hover"

I am trying to show a css animation when hovering on nav li a. So far I have tried several different examples on how to show and hide information from different elements but can get mine to work. Here is the CSS and HTMl, I do not provide any jS or jQuery since I could get any to work but below you have a jsfiddle ready to go. All help highly appreciated.
.box {
-webkit-animation: dropdownbar 1s ease;
-moz-animation: dropdownbar 1s ease;
-o-animation: dropdownbar 1s ease;
animation: dropdownbar 1s ease;
-webkit-animation-fill-mode: forwards;
-moz-animation-fill-mode: forwards;
-o-animation-fill-mode: forwards;
animation-fill-mode: forwards;
width:100%;
background-color:#000;
color:#fff
}
#-webkit-keyframes dropdownbar {
0% { height: 0px; }
100% { height: 35px; }
}
#-moz-keyframes dropdownbar {
0% { height: 0px; }
100% { height: 35px; }
}
#-o-keyframes dropdownbar {
0% { height: 0px; }
100% { height: 35px; }
}
#keyframes dropdownbar {
0% { height: 0px; }
100% { height: 35px; }
}
<nav class="nav">
<ul>
<li class="navLink">Home</li>
<li class="navLink">Away</li>
</ul>
</nav>
<div class="box">this should show only when hovering li element</div>
FIDDLE
You can use jQuery to trigger the CSS3 animation with a class change :
DEMO
CSS :
.box {
-webkit-animation-fill-mode: forwards;
-moz-animation-fill-mode: forwards;
-o-animation-fill-mode: forwards;
animation-fill-mode: forwards;
width:100%;
background-color:#000;
color:#fff;
height:0;
}
.box.show {
-webkit-animation: dropdownbar 1s ease;
-moz-animation: dropdownbar 1s ease;
-o-animation: dropdownbar 1s ease;
animation: dropdownbar 1s ease;
height:35px;
}
#-webkit-keyframes dropdownbar {
0% {height: 0px;}
100% {height: 35px;}
}
#-moz-keyframes dropdownbar {
0% {height: 0px;}
100% {height: 35px;}
}
#-o-keyframes dropdownbar {
0% {height: 0px;}
100% {height: 35px;}
}
#keyframes dropdownbar {
0% {height: 0px;}
100% {height: 35px;}
}
jQuery :
$('nav li a').hover(function () {
$('.box').toggleClass('show');
});
You can try this jQuery. You just have to modify it to your needs... but this should get you started.
$(".navLink").mouseenter(function(){
$(".box").css("visibility", "visible")
});
$(".navLink").mouseleave(function(){
$(".box").css("visibility", "hidden")
});
If you put this in your javascript part in jsFiddle, it works.
You have to add style for div box as
<div class="box" style="display:none">
and add following javascript code:
$(document).ready(function(){
$(".navLink").hover(function(){
$(".box").toggle();
});
});
See the updated fiddle: Updated fiddle
There you go :). assumes jquery is up and running!
$(document).ready(function() {
var divToShow = $('.box');
var links = $('.navLink');
var fadeDuration = 500;
//initial hiding of div
divToShow.hide();
//add listener when mouse enters hover-state on link
links.mouseenter(function() {
//stop animation if there is one
divToShow.stop();
//fade it in
divToShow.fadeIn();
});
//add listener for when mouse leaves link
links.mouseleave(function() {
//stop animation if there is one
divToShow.stop();
//fade it out
divToShow.fadeOut();
});
});
this initially hides your div and fades it in and out when hovered. Compared to the other solutions this also takes care of switching from hovering from one link to another without appruptly changing the animation. totally smooth... ;)
Just select jQuery 2.1 and paste this in you jsFiddle...should work immediately!

ng-animate doesn't let animation be finished

I have set animations on ng-view to fade for 1 second, but it doesn't let the animation out be finished:
.fadethis {
&.ng-enter, &.ng-leave {
-webkit-transition: all linear 1s;
-moz-transition: all linear 1s;
transition: all linear 1s;
display: block !important;
}
&.ng-enter, &.ng-leave.ng-leave-active {
opacity:0;
}
&.ng-leave, &.ng-enter.ng-enter-active {
opacity:1;
}
}
can't I make angular-animate finish the 1 second animation first?
DEMO: http://jsfiddle.net/bnyJ6/79/
It does not look like your view is actually fading out in your example. If it did, the page you are navigating to would appear and begin fading in before the previous page had finished fading out.
Currently I believe the easiest way to simulate the animations waiting for each other is to add a transition-delay to the enter animation (source).
This can get messy though. In your example the page you are navigating to would still begin to take up space before fading in and bump down the page that is fading out. You can get around this by setting your view to position: absolute;.
Demo without transition-delay: http://jsfiddle.net/5evFx/
Demo with transition-delay and position: absolute: http://jsfiddle.net/spKnX/
Working markup:
<div ng-view class="view fadein fadeout"></div>
Working CSS:
.fadein.ng-enter,
.fadeout.ng-leave {
-webkit-transition: all linear 1s;
-moz-transition: all linear 1s;
-o-transition: all linear 1s;
transition: all linear 1s;
display: block !important;
}
.fadein.ng-enter {
opacity: 0;
}
.fadeout.ng-leave {
opacity: 1;
}
.fadein.ng-enter.ng-enter-active {
transition-delay: 1s;
opacity: 1;
}
.fadeout.ng-leave-active {
opacity: 0;
}
html, body, .container {
height: 100%;
}
.view {
position: absolute;
}

Categories