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

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

Related

Show size value of element during CSS transition

When a user scroll to certain element on my page I add class which starts an animation of the width of it. I starts of with a width of 0% then goes up to 99% for example. As this animates is there a way to display this width incrementing in the page in HTML ie a <p> tag with this value incrementing?
The CSS is just this, I add the class .active when the user scrolls to it with Javascript.
.graph-horiz-bar__bar{
background:$niagara;
top:0px;
position:absolute;
left:0px;
width:0;
height:100%;
transition: width 0.3s;
}
.graph-horiz-bar__bar.active{
width:100%;
transition: width 0.3s;
}
var div = document.getElementById("yourDiv"), parapgraph = document.getElementById("yourParagraph");
setInterval(function(){
paragraph.innerHTML = div.offsetWidth + "px";
}, 20);
This sets the paragraphs content to the div's width every 20 ms.
The simplest way would be to animate the element width using jQuery .animate() and reading the current width from the step: parameter callback (Read the Docs)...
Using CSS3 transition:
var $bar = $("#bar"),
$currWidth = $("#currWidth"),
itv = null;
$("#bar").on({
// START COUNTING THE WIDTH
// I used a custom "start" event cause currently (2016)
// Event.transitionstart is implemented only in IE10+, Edge
start : function(){
$(this).addClass("active");
itv = setInterval(function(){
$currWidth.text($bar[0].offsetWidth);
},10);
},
// STOP COUNTING THE WIDTH
transitionend : function() {
clearInterval(itv);
$currWidth.text("INTERVAL STOPPED");
}
});
$("#start").on("click", function(){ // CLICK JUST FOR DEMO,
// You need to place this trigger inside your inViewport method
// when the element enters the viewport
$bar.trigger("start"); // <<----------------
});
#bar{
height: 20px;
width:0;
background:red;
transition: 3s;
}
#bar.active{
width:100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="start">ACTIVATE BAR</button><!-- TRIGGER BUTTON JUST FOR DEMO -->
width <span id="currWidth">0</span>
<div id="bar"></div>
When transitionstart will be implemented by all major browsers than the code would look pretty much like:
var itv;
$("#bar").on({
transitionstart: function(){
itv = setInterval(function(){
console.log( $bar[0].offsetWidth );
},10);
},
transitionend : clearInterval(itv)
});
$("#bar").addClass("active"); // place this call where needed
Probably some day in another galaxy some event like transitionstep could be all it takes....
$("#bar").on("transitionstep", function(){ // :(
console.log( this.offsetWidth );
});

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

Fading in and out text in block

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 */
}

Jquery Fadein/FadeOut simultaneously

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 () {

JQuery Fade On Hover Effect - help?

I'm trying to achieve a fade-on-hover effect with JQuery. Currently I have an element with a "hov" class attacked to it, without javascript the css will simply change it's color on :hover. With JQuery.
The idea is to clone the element as it's rolled over and place it directly infront, stripping it of the "hov" class so it's just static. Then I fade it out so it create the transition effect.
I'm having trouble though, after I strip the "hov" class from the clone, it KEEPS acting as though its still there. I can mouse over the clone even though it shouldn't be able to be targeted through hov. Any ideas / tips?
<a href="#" class="hov rounded-50 action-button">Fade Me Out< /a>
$(".hov").mouseover(function() {
// Clone the current element, remove the "hov" class so it won't trigger same behavior
// finally layer it infront of current element
var $overlay = $(this).clone(true).removeClass("hov").insertAfter($(this));
// Push it to the side just for testing purposes - fade it out
$overlay.css({left:'300px'}).fadeOut({duration:500, ease:'easeOutQuad'});
});
No need to clone the element, just fade the original element:
$('.hov').mouseenter(function() {
$(this).fadeOut();
});
// Optionally:
$('.hov').mouseleave(function() {
$(this).stop(true, true).show();
});
You can also use the hover function:
$('.hov').hover(function(){
$(this).fadeOut();
},
function(){
$(this).stop(true, true).show();
});
If you just want it to partially fade, you can animate the opacity property:
$('.hov').mouseenter(function() {
$(this).animate({'opacity': 0.5});
});
If you just want it to pulse, then return to normal opacity:
$('.hov').mouseenter(function() {
$this = $(this);
$this.animate({'opacity': 0.5}, {
'complete': function(){
$this.animate({'opacity': 1});
}
});
});
Finally, if your willing to forgo support of older browsers, you can do it all with css:
.hov {
-webkit-transition: opacity 0.3s ease-in;
-moz-transition: opacity 0.3s ease-in;
}
.hov:hover {
opacity: 0.5;
}

Categories

Resources