Jquery Fadein/FadeOut simultaneously - javascript

How are you?
This is from a previous post and a solution was posted.
JS :
$(document).ready(function() {
var allBoxes = $("div.boxes").children("div");
transitionBox(null, allBoxes.first());
});
function transitionBox(from, to) {
function next() {
var nextTo;
if (to.is(":last-child")) {
nextTo = to.closest(".boxes").children("div").first();
} else {
nextTo = to.next();
}
to.fadeIn(500, function() {
setTimeout(function() {
transitionBox(to, nextTo);
}, 5000);
});
}
if (from) {
from.fadeOut(500, next);
} else {
next();
}
}
JSFIDDLE HERE
However I was trying to extend this a bit, where when box 1 fades out, you can see box 2 fading in slightly at the same time - simultaneously, and as box2 fades out ...box 3 is fading in at the same time with the opacity going from 0 to 1

I'm fine and you? :') .
I have a solution that maybe can help.
Have you tried making 1 class named display and setting display: block; and then put it on the function as toggleClass(). Finally you make a new class named as .transition(I do this with all my project to make them easier) and put it on the div or add it with some code like: $("div").addClass("transition");.
the code for .transition should be like this:
.transition {
-webkit-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
}
You can also try insted of CSS and jQuery using only CSS.
an example could be using CSS Animations. Define the class of every box and then make a animation and add a delay on every animation so it will show every certain time, make them infinite so the will loop.
Hope you understand :)

Editing line 14 of your jsFiddle to add a delay created a smoother effect so you don't see two at once. Which I surmise is the answer to the question.
Line 14 edits: to.delay(100).fadeIn(500, function () {

Related

how to know opacity value using javascript?

I am using transition: opacity 5s; property. I want to show different alert or console message when my opacity value is 0.4 or 0.6 or .2 . on button click I am doing transition but I want to know opacity progress so that i will show those message ?
is there any way to do this
var btn = document.querySelector("button");
var par = document.querySelector("#parId");
btn.addEventListener("click", (e) => {
par.classList.add("removed");
});
par.addEventListener("transitionend", () => {
par.remove();
});
#parId {
transition: opacity 5s;
}
.removed {
opacity: 0;
}
we are getting transitionend callback if there any progress callback where I will check opacity value ?
There is no event that can be listened to to give what you want - unless you are going to use a linear transition. In that case you can carve your changes of opacity up into 0.2s slots, changing opacity on transitionend to the next value down - 0.8, 0.6 etc.
Your code however takes the default for the transition-timing-function property which is ease - not linear - so transitionend is of no use to you.
This snippet polls the opacity changes every tenth of a second and writes the current opacity to the console so you can see what is happening.
A couple of points: you will have to check for when the opacity goes just less than one of your break points, you are unlikely every to hit it just at exactly 0.6s or whatever; also notice that the console carries on being written to after the element has totally disappeared. The timing will not be exact, things are happening asynchronously.
<style>
#parId {
transition: opacity 5s;
width: 50vw;
height: 50vh;
background: blue;
opacity: 1;
display: inline-block;
}
.removed {
opacity: 0;
}
</style>
<div id="parId"></div>
<button>Click me</div>
<script>
var btn = document.querySelector("button");
var par = document.querySelector("#parId");
btn.addEventListener("click", (e) => {
let interval = setInterval(function () {
const opacity = window.getComputedStyle(par).opacity
console.log(opacity);
if (opacity == 0) {clearInterval(interval);}
}, 100);
par.style.opacity = 0;
});
</script>
You could potentially check periodically like this, although your interval will need to be at least the speed of the opacity animation or be quicker than it to catch the values.
var par = document.querySelector("#parId");
setInterval(function() {
console.log(window.getComputedStyle(par).opacity);
}, 100)
#parId{
opacity: 0.2;
transition: opacity 3s ease-in-out;
}
#parId:hover {
opacity: 1;
}
<div id="parId">
test
</div>
Take a look in this example
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/animationend_event
You could define your animation stages as diferent ranimations on css then call them in chain via javascript. Before, you must set an event listener for the animationend event, and every time the event is fired you check the #parId opacity.
You could do it.with jQuery to, totaly in javascript

JS changing source image with animation

I have a problem with looped fade-in/fade-out image source changing in JS and CSS and using SetTimeout() callback.
The problem is, that the sequence is working strange: sometimes the image changes before the transition starts, sometimes it works fine, and sometimes in the other way.
Here is my JS:
const animationTime = 5000;
const transitionTime = 500;
function nextImage() {
let img = document.getElementById('img1');
img.classList.remove('hidden');
setTimeout(function () {
img.classList.add('hidden');
},animationTime-transitionTime);
img.src=randomize();
setTimeout(nextImage, animationTime);
}
randomize() function just gets a random image path from array.
Here is HTML:
<div class="some-class">
<img class="some-image" id="img1" src="1.png">
</div>
And here is CSS:
.some-image {
transition: opacity 0.5s linear;
-webkit-transition: opacity 0.5s linear;
-o-transition: opacity 0.5s linear;
-moz-transition: opacity 0.5s linear;
-moz-border-radius: 15px;
}
.hidden {
opacity: 0;
}
Upd.
So I have edited CSS file:
.some-image {
width: 370px;
height: 190px;
animation: fade-out;
animation-duration: 1s;
}
.hidden {
animation: fade-out;
animation-duration: 1s;
}
#keyframes fade-in {
from {opacity: 0;}
to {opacity: 1;}
}
#keyframes fade-out {
from {opacity: 1}
to {opacity: 0}
}
And JS-file:
function nextImage() {
let img = document.getElementById('img1');
img.classList.remove('hidden');
setTimeout(function () {
img.classList.add('hidden');
},animationTime-1000);
img.src=randomize();
}
setTimeout(nextImage, animationTime);
}
And, somehow, it works perfectly on a local machine, but on a dedicated website animation sometimes fades-in before the image source changed.
I think the problem is about timing. The setTimeout function didn't guarantee to execute exactly time as argument set. So there is a possibility that you change the src of image before/after it add/remove hidden class. These delay is rarely happens that might be the reason why it works on your machine.
So this problem can solve by every time you change the image you must have to make sure the image is completely hide.
const nextImage = function () {
let img = document.querySelector('img')
img.classList.add('hidden')
setTimeout(() => {
img.style.visibility = 'hidden'
img.src = randomImage()
// skip to next frame, may be this not necessary to use setTimeout
setTimeout(() => {
img.style.visibility = ''
img.classList.remove('hidden')
}, 10)
}, animationDuration)
setTimeout(nextImage, intervalDuration + animationDuration)
}
The new cycle will be: fade image out, wait for animation then change image (with set visibility to hidden) and then fade in. And loop.
With this approach. If setTimeout is early execute before the image has completely fade out the visibility will be set hidden. If it's delayed, the image will be hide a bit longer.
Live example here. In that code I add a little bit noise with random time to test.
Unfortunately, After I spent an hour to see my answer is right I still feel it's not perfect anyway and it will be worse if you image is large. I would recommend you try two or more img tags instead.
You should try using css animations instead. You can easily implement the above with it, and it will save you the trouble of handling animations in your code.

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);

Categories

Resources