Fading in and out text in block - javascript

I have a block which content is being dynamically changed by script and I want that content not to change instantly, but fade out and then fade in with new content.
I want that done without jQuery — pure JS and CSS.
I am trying to do this in such a way:
I've defined transparent and opacle classes in CSS with transition set to 2s, and wanna toggle that classes for block with content when the content changes. As I expect it should smoothly fade out old content and fade in new content. But in fact content just changes instantly.
CSS:
.non-opacle {
opacity:0;
transition: opacity 2s linear;
}
.opacle {
opacity:1;
transition: opacity 2s linear;
}
HTML
<div class="alert alert-info" id="wrapper">
<p id="text-box">…</p>
</div>
JS
var textBox = document.getElementById('text-box');
window.onload = function () {
var failCounter = 0;
var current = notes[Math.floor(Math.random() * 12)];
textBox.className = 'opacle';
textBox.innerHTML = '…';
function keyClicked(event) {
if (event.target.className.split(' ')[1] === current) {
textBox.className = 'non-opacle';
textBox.innerHTML = '*some altered content*';
textBox.className = 'opacle';
…
In JS I initially set content wrapper block to 'opacle' class with initial content, and then on certain conditions, I set it to 'non-opacle', change block's innerHTML to place relevant content, and set the class back to 'opacle'.
But no animation occurs( What am I doing wrong?

Your problem is that you're adding and removing the opacity at the same time, before the initial transition has had time to complete.
What you need to do is delay the changing of the innerHTML and resetting of the opacity until the transition has completed.
Here's a very simple looping example to illustrate the principle, the important part to note is the setTimeout.
var p=document.getElementById("change"),text=["One","Two","Three","Four","Five"],x=0,interval=setInterval(function(){
x++;if(x===text.length)x=0;
p.classList.add("hide");
setTimeout(function(){
p.innerHTML=text[x];
p.classList.remove("hide");
},500);
},2000);
#change{
color:#000;
font-family:arial;
padding:5px;
transition:opacity .5s linear;
}
.hide{
opacity:0;
}
<p id="change">One</p>

The browser is not going to wait for transitions to complete before setting the class back to opacle.
This simple working fiddle moves the transition out to a separate selector, and uses a transitionend event listener, to wait for the element to be completely faded out before changing the content and fading it back in.
http://jsfiddle.net/0m3Lpwxo/1/
CSS:
.opacle {
opacity:1;
}
.non-opacle {
opacity:0;
}
#test {
transition: opacity 1s linear;
}
html:
<div id="test" class="non-opacle">this is content</div>
<button onclick="toggle()">toggle</button>
js:
function transitionEnded() {
var el = document.getElementById('test');
el.innerHTML = "hello.";
el.classList.remove('non-opacle');
}
function toggle() {
var el = document.getElementById('test');
el.addEventListener("transitionend", transitionEnded, true);
el.classList.add('non-opacle');
}

You probably just need to define browser specific styles along side your current definition (for example: -webkit-transition: opacity 2s linear;)
Also, I would say that instead of adding the transition redundantly to both classes, target something about your element that's not going to change, like its ID and define the transition style rules there. That way you will keep your CSS more DRY.
Here's the best reference material for dealing with CSS transitions: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions

Try this:
<div id="myElement">Text</div>
function fadeOut(id,val){
if(isNaN(val)){ val = 9;}
document.getElementById(id).style.opacity='0.'+val;
//For IE
document.getElementById(id).style.filter='alpha(opacity='+val+'0)';
if(val>0){
val--;
setTimeout('fadeOut("'+id+'",'+val+')',90);
}else{return;}
}
function fadeIn(id,val){
if(isNaN(val)){ val = 0;}
document.getElementById(id).style.opacity='0.'+val;
//For IE
document.getElementById(id).style.filter='alpha(opacity='+val+'0)';
if(val<9){
val++;
setTimeout('fadeIn("'+id+'",'+val+')',90);
}else{return;}
}
Referred from this.

I have used following JS:
function change(){
var d = document.getElementById("div");
d.className = d.className + " non-opacle";
setTimeout(function(){
d.className = "opacle";
d.innerHTML = "TEST";
},1000);
}
See following DEMO, with CSS:
.opacle {
opacity:1;
transition: opacity 1s linear;
}
.non-opacle {
opacity:0;/* No need to add transaction here */
}

Related

How to stop one eventListener when start another on the same element?

I'm creating some kind of gallery in js as a practice. I found an error and I don't know how to solve it.
Full code of on JSFiddle ->
Code
Background
I add two eventListeners to my img wrapper,
wrapper looks like that:
<div class="gallery-item"> <-- wrapper
<img src=""> <-- image
<div> <-- overlay
</div>
</div>
and listeners like that (listeners I'm adding during creating wrappers in js):
imageWrapper.addEventListener('mouseenter', enableOverlay, false);
imageWrapper.addEventListener('mouseleave', disableOverlay, false);
Listeners invokes functions, which are responsible for displaying overlay over image. First of them show overlay with fade effect and the second one hide it with the same effect.
enableOverlay
function enableOverlay(e) {
var el = this.childNodes[1].style;
el.display = 'block';
(function fadeIn() {
if (el.opacity < 1) {
el.opacity = parseFloat(el.opacity) + Number(0.1);
setTimeout(fadeIn, 30);
}
}());
}
disableOverlay
function disableOverlay(e) {
var el = this.childNodes[1].style;
(function fadeOut() {
if (el.opacity > 0) {
el.opacity = parseFloat(el.opacity) - Number(0.1);
setTimeout(fadeOut, 30);
} else {
el.display = 'none';
}
}());
}
Problem
On first sight everything is ok if I'm slowly move mouse over images - one function ends (opacity = 1) and the second is starting until opacity = 0. But when I'm moving mouse fast over images, overlays start to blink - opacity increases and decreases by 0.1 (value in IIFEs) and script loop.
As I figured out, reason of this behavior is that enableOverlay dosen't finish (el.opacity dosen't reach 1) and in the same time disableOverlay starts. And I don't know how to fix this situation.
I was trying to deal with it using flags which represents the state of fading function and breaks IFFEs, but it didn't help.
Long story short, can anyone help me with this problem or show me a way of thinking to solve it?
EDIT
In my opinion, my problem is 'how to stop function in one eventListener when another eventListeners is fired'. Changing opacity is only a sample.
You can use css transition.
function enableOverlay(e) {
var el = this.childNodes[1].style;
el.opacity = '1';
}
function disableOverlay(e) {
var el = this.childNodes[1].style;
el.opacity = '0';
}
.gallery-item img+div {
cursor: pointer;
opacity: 0;
-webkit-transition: opacity .3s ease;
-moz-transition: opacity .3s ease;
-o-transition: opacity .3s ease;
-ms-transition: opacity .3s ease;
transition: opacity .3s ease;
}
https://jsfiddle.net/zjqpxzmj/
Just added an attribute to track the event.
Fiddle
function disableOverlay(e) {
var el = this.childNodes[1].style;
var that = this.childNodes[1];
that.setAttribute('op','fadeOut');
(function fadeOut() {
if (el.opacity > 0 && that.getAttribute('op')==='fadeOut') {
el.opacity = parseFloat(el.opacity) - Number(0.1);
setTimeout(fadeOut, 30);
} else {
el.display = 'none';
}
}());
}
In your case, catching the latest setTimeout and calling clearTimeout on it from the other function should help.

Jquery - Reverse animation on click (toggle or if/else)

I've tried a lot of different options and I'm sure most would work if I knew what I was doing.
I want to click on an image and make it larger and centered in the screen, then I want to click on the same image and return it back to normal.
In the two individual scripts below I have erased the reverse effect but I basically used functions that changed the css settings back to width:250, height:250, and marginLeft:9%. All I could get it to do successfully was enlarge an image but then it shrank automatically once it had fully enlarged. I need to make the function enlarge and then wait until I click the image again for it to shrink.
<script>
$('document').ready(function(){
$('.hello_mom').on('click', function(){
$('.lbs_lease').animate({
width:"350px",
height:"350px",
zIndex:"10",
marginLeft:"28.4%"
}, 500 );
});
});
</script>
<!--<script>//My idea with this second script was to set an initial variable that I would use to make the enlargement animation run (with an if statement) and the shrinking animation stop until the variable was changed at the end of the function. Once the variable changes the else statement would become true and run my reverse animation. However, it seems redundant when the animation still doesn't wait for another click to occur before it runs.
$a = 5;
$c = 10;
var b = $a;
if(b < $c) {
$('.lbs_lease').animate({
width:"350px",
height:"350px",
zIndex:"10",
marginLeft:"28.4%"
}, 500 )};
</script>-->
you have 2 ways to do that ..
1- by using addClass and removeClass with transition
in css
.imageClicked{
width:350px;
height:350px;
zIndex:10;
marginLeft:28.4%;
transition : 0.5;
}
js
$('document').ready(function(){
$('.hello_mom').on('click', function(){
if($('.lbs_lease').hasClass('imageClicked')){
$('.lbs_lease').removeClass('imageClicked');
}else{
$('.lbs_lease').addClass('imageClicked');
}
});
});
2- by make another animate with default style and use boolean true or false
$('document').ready(function(){
var imgClicked = true;
$('.hello_mom').on('click', function(){
if(imgClicked == true){
$('.lbs_lease').animate({
width:"350px",
height:"350px",
zIndex:"10",
marginLeft:"28.4%"
}, 500 );
imgClicked = false;
}else{
$('.lbs_lease').animate({
//type your default style here
}, 500 );
imgClicked = true;
}
});
});
something like this:
var left = true;
$('.hello_mom').on('click', function () {
if (left) {
$(this).animate({
'marginLeft': "-=30px"
});
left = false;
} else {
$(this).animate({
'marginLeft': "+=30px"
});
left = true;
}
});
http://jsfiddle.net/e1cy8nLm/
You can do something like this: JSFiddle Demo
$('img').on('click', function(){
$(this).toggleClass( 'enlarge' );
});
CSS:
img {
// set the initial height and width here so we can animate these properties.
width:100px;
height:100px;
-webkit-transition: all 1s ease-in-out;
-moz-transition: all 1s ease-in-out;
-o-transition: all 1s ease-in-out;
transition: all 1s ease-in-out;
}
// toggle this class with jQuery to enlarge the img on click
.enlarge {
width:200px;
height:200px;
}
One of the methods will be using addClass and removeClass jquery functions keeping track of the current state of image.
The enlarged variable has the current state of the image and toggles it onclick with addition or removal of class.
Note the transition time is mentioned for both the classes, the added/removed as well as the original styling class to prevent abrupt transition while resizing to both states.
Here is a jsfiddle for that : JS FIDDLE DEMO
HTML Code :
<div>
<img class="hello_mom" src="http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image1.jpg" />
</div>
CSS Code :
.hello_mom{
width:250px;
height:250px;
background : red;
-webkit-transition: all 0.5s; /* Safari */
transition: all 0.5s;
}
.hov_class{
width:350px;
height:350px;
z-index:10;
//margin-left:28.4%;
-webkit-transition: all 0.5s; /* Safari */
transition: all 0.5s;
}
JS Code :
var enlarged=0;
$('document').ready(function(){
$('.hello_mom').on('click', function(){
if(!enlarged){
$('.hello_mom').addClass("hov_class");
enlarged=1;
}
else{
$('.hello_mom').removeClass("hov_class");
enlarged=0;
}
});
});
Take a look at this
http://julian.com/research/velocity/
Velocity is javascript animation, made faster than CSS animation.
...and here you also have a reverse method

Apply class to divs within HTML being AJAX called?

I am appending new HTML on a load more button, like this:
function addStuff() {
$.get('page-partials/more-stuff.html', function(stuff) {
$('#load-button').append(stuff);
});
};
The trouble is that this new content is being put into a container (with a dynamic height), which I want to animate down when more things are added. For this reason, I need to add a dynamic class to divs inside 'more-stuff.html', each time that template is added again.
Eg:
<div class='stuff added1'></div>
And then the next time it's added:
<div class='stuff added2'></div>
Etc. Is this possible? Otherwise, does anyone know of a solution to animate height changes from an undetermined non-zero number to another undetermined non-zero number?
What about
var count = 0;
$.get('page-partials/more-stuff.html', function(stuff) {
count++;
$('#load-button').append(stuff).addClass('stuff added'+count);
});
Actually vivek mentioned a better approach but that has to be something like this:
var stuff = '<div style="height:200px;">Dynamically appended div</div>'; // ajax response
var h = $(stuff).height();// find out the height of it.
$('.stuff').append(stuff).css('height', h); // after append just update the height.
.stuff {
height:60px;
width:100px;
border:2px solid #f00;
-webkit-transition: height 0.8s ease-in-out;
-moz-transition: height 0.8s ease-in-out;
-o-transition: height 0.8s ease-in-out;
transition: height 0.8s ease-in-out; /* <------css3 transition to animate the height */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='stuff'></div>
Try chaining added function to each call to addStuff
function addStuff() {
// `return` jQuery promise object from `addStuff`
return $.get('page-partials/more-stuff.html', function(stuff) {
$('#load-button').append(stuff);
});
};
var added = function() {
$(".stuff").each(function(index) {
$(this).addClass("added" + index + 1)
})
}
addStuff().then(added);

Change button background image, text and shape on hover at the same time

I am wondering if it is possible to make a button background image or text change to another text or image along with the button shape on mouse hover?
Say I had a button having a certain text or background image shoving the symbol ✓ (checkmark) and I wish it to change shape (from a circle to a rectangle) and text (from checkmark to the word submit) on mouse hover.
Is it possible using CSS, JS or both?
Without Changing Animations
JSFiddle
If you just want to change the background image and shape, you can use pure CSS
.button {
height:30px;
width:60px;
-webkit-border-radius:15px;
-moz-border-radius:15px;
border-radius:15px;
background-image:url(...)
}
.button:hover {
-webkit-border-radius:0px;
-moz-border-radius:0px;
border-radius:0px;
background-image:url(...)
}
If you want to change the text, you need JavaScript.
<style>
#button {
height:30px;
width:60px;
border-radius:15px;
background-image:url(img1.png);
}
</style>
<script>
function mouseOver() {
document.getElementById("button").style.backgroundImage = "url(img2.png)";
document.getElementById("button").style.borderRadius = "0px";
document.getElementById("button").innerHTML = "Submit";
}
function mouseOut() {
document.getElementById("button").style.backgroundImage = "url(img1.png)";
document.getElementById("button").style.borderRadius = "15px";
document.getElementById("button").innerHTML = "✓";
}
</script>
<div id="button" onmouseover="mouseOver()" onmouseout="mouseOut()">✓</div>
With Changing Animations
JSFiddle
To animate the button, use the
-webkit-transition:all 0.2s;
transition:all 0.2s;
functions. Every property that is changed in the :hover css, is automatically animated with a duration of 0.2 seconds.
If you also want the text to change (in my example fading in and out) it gets a little more complicated. (Disclaimer: My solution is probably not the most elegant one, but it works.)
Add two more classes to your CSS, .fade-out and .fade-in.
.fade-out {
opacity: 1;
animation: fadeOut 0.2s;
}
.fade-in {
opacity: 0;
animation: fadeIn 0.2s;
}
In this case I wanted the text animation to be a little longer than the border animation (I think it looks better), but if they should be the same length, you have to set each of the animations to 0.1s
Then add two #keyframes animations, fadeOut and fadeIn like this:
#keyframes fadeOut {
from {opacity: 1;}
to {opacity: 0;}
}
#keyframes fadeIn {
from {opacity: 0;}
to {opacity: 1;}
}
Now the tricky part, the JavaScript:
function mouseIsOver() {
btn = document.getElementById("button_java");
btn.childNodes[0].className += ' fade-out';
setTimeout(function(){
btn.childNodes[0].innerHTML = "Submit";
btn.childNodes[0].className = btn.childNodes[0].className.replace(' fade-out', '');
btn.childNodes[0].className += ' fade-in';
setTimeout(function(){
btn.childNodes[0].className = btn.childNodes[0].className.replace(' fade-in', '');
}, 200);
}, 200);
}
function mouseIsOut() {
btn = document.getElementById("button_java");
btn.childNodes[0].className += ' fade-out';
setTimeout(function(){
btn.childNodes[0].innerHTML = "✓";
btn.childNodes[0].className = btn.childNodes[0].className.replace(' fade-out', '');
btn.childNodes[0].className += ' fade-in';
setTimeout(function(){
btn.childNodes[0].className = btn.childNodes[0].className.replace(' fade-in', '');
}, 200);
}, 200);
}
childNodes[0] gets all inner children (tags), and chooses the first one
className += ' fade-out' adds the class 'fade-out' to the elements class list. There needs to be a space in front of the added class name, just so if there are classes already defined, they won't combine into one non-existent class
setTimeout(function,waitduration) runs the code in function after it waitet waitduration milliseconds. Match this length to the duration of your animation in the .fade-out{...} class in your CSS-file
className.replace(' fade-out','') replaces the fade-out class in the elements list of classes with an empty string to remove it. Don't forget to remove the space, too.
Your Personalized Button
JSFiddle or PasteBin
I've copied the code from your page, added a <p> wrap around the text in the button, and added
.button p {
line-height:1em;
margin:0;
}
to the CSS.
Then you need to import jQuery by adding
<script src="http://code.jquery.com/jquery-2.1.3.js"></script>
into the head. Then add another code snippet,
<script type="text/javascript">
$( document ).ready(function() {
$("#subscribe_button").hover(
function() {
txt = $("#subscribe_button").children("p");
txt.fadeOut(100, function() {
txt.html("Sottoscrivi");
txt.fadeIn();
});
}, function() {
txt = $("#subscribe_button").children("p");
txt.stop(true,false).fadeOut(100, function() {
txt.html("✓");
txt.fadeIn();
});
}
);
});
</script>
That should be it!

CSS3 and Javascript: fade text out and then in using the same function

I'm trying to create a fading out and fading in effect using JavaScript and CSS3. The goal is to have a div shrink in width when clicked and have the text contained within it simultaneously fade out. Then when it is clicked again, the div expands back to its normal width, and the text fades back in.
Here is the HTML:
<div id="box1" onclick="slide1()">
<p class="fader">Lorem ipsum.</p>
</div>
Here is the CSS:
#box1 {
position:relative;
left:0%;
top:0%;
width: 70%;
height: 100%;
background-color: #666;
z-index:4;
}
Here is the javascript:
var box1
var fader
window.onload = function() {
box1 = document.getElementById('box1');
fader = document.getElementsByClassName('fader');
}
function slide1(){
if(box1.style.width=='10%'){
box1.style.width='70%';
fader[0].style.opacity='1';
fader[0].style.transition='opacity 0.25s ease-in';
}
else {
box1.style.width='10%';
fader[0].style.opacity='0';
fader[0].style.transition='opacity 0.75s ease-in';
}
}
It's working for the fade-out, but for the fade-in it is immediately transitioning from 0 opacity to 1 opacity... there's no fade-in. Any ideas?
I actually asked a very similar question with the same issue a while back: Opacity effect works from 1.0 to 0, but not 0 to 1.0. Check the out and see if it works for you.
Otherwise, try adding a class to the fader element instead of adding a style declaration. Then, in your actual CSS, write the code for the fader element transition.
I guess you use even firefox or opera? I think your code won't work on safari or chrome since transition needs webkit-prefix on those browsers. You can use following code to get transition support:
var transform = (function () {
var transforms = [
'OTransform',
'MozTransform',
'msTransform',
'WebkitTransform'
], transform = 'transform';
while (transform) {
if (document.body.style[transform] === undefined) {
transform = transforms.pop();
} else {
return transform;
}
}
return false;
}());
When im using CSS-transition, sometimes I change transition style and then let browser update changes before changing other styles. You can do this with timeout. On some browsers I have noticed that animation is not working unless doing that (some firefox browsers).
fader[0].style.transition='opacity 0.75s ease-in';
setTimeout(function () {
box1.style.width='10%';
fader[0].style.opacity='0';
}, 4);

Categories

Resources