Why animate's callback function (complete) executed at start? - javascript

Duplicate:
Yes it is but a little bit different from this.
I'm using jQuery 3.1.0 This is my code:
$(document).ready(function () {
ToggleAsideBar();
});
function ToggleAsideBar(){
$(".ah-sidebar-toggle").click(function(){
let toggleSize = $(".ah-logo").width() == 230 ? "50px" : "230px";
$(".ah-logo").animate(
{ width: toggleSize },200,"linear",function () {alert("Animation Complete!");'}
);
});
}
Problem:
In my case, alert show before the animation starts. I want to show alert after the animation completed. Any thoughts what I am doing wrong in above code?
Live Example:
jsfiddle

You had a collision between jquery's animation and css's transition.
If you decide to use animate - you should remove the transition lines from your css file.
Here is a working version (without the transition in your css):
$(document).ready(function () {
ToggleAsideBar();
});
function ToggleAsideBar(){
//Get width of browser
$(".ah-logo").click(function(){
let toggleSize = $(".ah-logo").width() == 230 ? "50px" : "230px";
$(".ah-logo").animate(
{ width: toggleSize },200,"swing"
).promise().done(function(){
alert("Animation Complete!");
});
});
}
.ah-logo {
width: 230px;
float: left;
font-weight: 600;
font-size: 16px;
text-align: center;
overflow: hidden;
}
a {
line-height: 50px;
display: block;
}
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<div class="ah-logo">
Admin
</div>

Related

Why isnt my $().css({ "visibility": "visible"}) working?

I can't seem to get my jquery <div id="NotificationDotOnNav" > {{NotificationNavDot}} </div> function to work!
Find below the helper file:
<template name="home">
<div id="NotificationDotOnNav" > {{NotificationNavDot}} </div>
</template>
Find below my helper file:
Template.home.helpers({
'NotificationNavDot': function () {
var numberOfNotifications = recipientsDetails.find({counts:1}).count();
if (numberOfNotifications > 0) {
$("#NotificationDotOnNav").css({ "visibility": "visible"});
alert("Testing!");
return;
}
else {
$("#NotificationDotOnNav").css({ "visibility": "hidden"});
}
},
});
When run, a popup with Testing! displays, clearly meaning the flow actually enters the if (numberOfNotifications > 0), however the $("#NotificationDotOnNav").css({ "visibility": "visible"}); fails to fire up!
What I find very strange is that, when copy & paste and run: $("#NotificationDotOnNav").css({ "visibility": "visible"}); in the browser console, it works!
Can someone kindly explain why it only fires-up when run in the browser console and not otherwise? Also kindly help me get this simple code to work.
I have included the relevant CSS file, in case this will help
#NotificationDotOnNav{
top: 10px;
float: right;
right: 5%;
visibility: hidden;
position: absolute;
z-index: 5;
min-width: 10px;
padding: 7px 7px;
border-radius: 20px;
background-color: #f54555ad;
}
Looking forward to your help!
Make sure your helper function execute after the Document Object Model (DOM) is ready and becomes safe to manipulate (this could be the reasons why your code runs when you type it in dev console but not when your run your js).
You can use $( document ).ready( handler ) (doc) for that.
Please consider a minimal reproducible example so we can help you out with more details.
By the way, you could also improve your code by caching the selector and using a ternary to write it more succinctly:
...
const numberOfNotifications = recipientsDetails.find({counts:1}).count();
const elm = $("#NotificationDotOnNav") // query the DOM just once
numberOfNotifications > 0 ? elm.show() : elm.hide()
...
Try it like this:
Template.home.helpers({
'NotificationNavDot': function () {
var numberOfNotifications = recipientsDetails.find({counts:1}).count();
if (numberOfNotifications > 0) {
$("#NotificationDotOnNav").css('opacity', '1');
alert("Testing!");
return;
} else {
$("#NotificationDotOnNav").css('opacity', '0');
}
}
});
Also change your CSS code:
#NotificationDotOnNav {
top: 10px;
float: right;
right: 5%;
opacity: 0; /* this has been changed */
position: absolute;
z-index: 5;
min-width: 10px;
padding: 7px 7px;
border-radius: 20px;
background-color: #f54555ad;
}
I found a walk around the issue that works.
Find below the changes that I've made to enable the code to work.
Find below updates I've made to my HTML code:
<template name="home">
<span id="NotificationDotOnNav" class="badge animated"> {{NotificationNavDot}} </span>
</template>
Find below my helper file:
Template.home.helpers({
'NotificationNavDot': function () {
var numberOfNotifications = recipientsDetails.find({counts:1}).count();
if (numberOfNotifications > 0 ) {
$("#NotificationDotOnNav").css({"visibility": "visible"});
return 0;
}
else {
$("#NotificationDotOnNav").css({ "visibility": "hidden"});
}
}
});
Find below my CSS:
#NotificationDotOnNav{
top: 11px;
float: right;
right: 10%;
height: 13px;
width: 1px;
position: fixed;
visibility: hidden;
z-index: 9;
font-size: xx-small;
color: #f5455500;
background-color: #f54555b5;
}
Nevertheless Id like to thank everyone for their contributions.

jquery .html() working only with alert()

I have a javascript function, using jQuery, which manipulates a <div id="message"> to print error and status messages.
It looks like this:
function messageShow(msg, type) {
$('#message').addClass("message red");
$('#message').html(msg);
$("#message").slideDown(200, 0).fadeTo(200, 1);
setTimeout(function() {
$("#message").fadeTo(500, 0).slideUp(500, 0);
}, 5000);
//alert('asdasd');
}
The content of the div is only seen if I uncomment the alert(); line.
There is no redirect after this, so the page is not changed before the content is loaded.
I tried:
$('#message').html(msg, function() { ... });
Just to be sure, but that doesn't work either.
The div:
<div id="message"></div>
The css:
.message {
border-radius: 5px;
width: 100%;
height: 20px;
padding: 10px;
vertical-align: middle;
line-height: 20px;
}
.red {
background: #daa;
color: #855;
}
I do recomend you to use jquery delay function instead.
Try this:
function messageShow(msg, type) {
$('#message').addClass("message red");
$('#message').html(msg);
$("#message").slideDown(200, 0).fadeTo(200, 1).delay( 500 ).fadeTo(500, 0).slideUp(500, 0);
}

Count back percentage using JQuery

I have the code below where I'd like to the numbers count back to 0% once hover the object out. Also I can't figure our how to make the value disappear again as it was on load. Could you please help me solve this.
Thanks in advance.
HTML
<div class="container">
<div class="fill" data-width="80%"></div>
</div>
<div class="container">
<div class="fill" data-width="50%"></div>
</div>
CSS
.container {
position: relative;
width: 300px;
height: 30px;
background-color: blue;
margin: 10px auto;
}
.fill {
height: 100%;
width: 0;
background-color: red;
line-height: 30px;
text-align: left;
z-index: 1;
text-align: right;
}
JQuery
$(function() {
$('.container').hover( function(){
var width=$(this).find(".fill").data('width');
$(this).find(".fill").animate({ width: width }, {
duration:800,
step: function(now, fx) {
$(this).html(Math.round(now) + '%');
}
});
},
function(){
$(this).find(".fill").animate({ "width": "0px" }, 800);
});
});
jsFiddle http://jsfiddle.net/zp8pe069/
jsBin demo
CSS: set overflow: hidden to .fill to prevent the text being visible after the animation ends.
HTML: remove % from the data attribute
JS and here you go. all you need:
$('.container').hover(function( e ){
var $fill = $(this).find(".fill");
var width = $fill.data('width');
$fill.stop().animate({width: e.type=="mouseenter" ? width+"%" : "0%" }, {
duration : 800,
step : function(now) {
$(this).html(Math.round(now) + '%') ;
}
});
});
Note also the use of the .stop() method, if you hover multiple time hysterically :) it'll prevent endless animations.

JQuery doesn't appear to be working in Wordpress

I have the following in the tags of the header in my wordpress theme, but no matter what it will not work.
<script>JQuery(function() {JQuery('#fader img:not(:first)').hide();JQuery('#fader img').css('position', 'absolute');JQuery('#fader img').css('top', '0px');JQuery('#fader img').css('left', '50%');JQuery('#fader img').each(function() {var img = JQuery(this);JQuery('<img>').attr('src', JQuery(this).attr('src')).load(function() {img.css('margin-left', -this.width / 2 + 'px');});});var pause = false;function fadeNext() {JQuery('#fader img').first().fadeOut().appendTo(JQuery('#fader'));JQuery('#fader img').first().fadeIn();}function fadePrev() {JQuery('#fader img').first().fadeOut();JQuery('#fader img').last().prependTo(JQuery('#fader')).fadeIn();}JQuery('#fader, #next').click(function() {fadeNext();});JQuery('#prev').click(function() {fadePrev();});JQuery('#fader, .button').hover(function() {pause = true;},function() {pause = false;});function doRotate() {if(!pause) {fadeNext();}}var rotate = setInterval(doRotate, 2000);});</script>
What a mess right? To show that I have been researching this, a previous answer said to remove all whitespaces and change all $ with JQuery. I want to simply fade between a few images in the fader ID.
I have even made a fade.js file, and included it in the functions file, to no avail.
Here is my CSS...
#fader {
position: relative;
width: 100%;
height: 400px;
}
.button {
background-color: green;
width: 50px;
height: 30px;
font-size: 20px;
line-height: 30px;
text-align: center;
position: absolute;
top: 30px;
}
#next {
right: 100px;
}
#prev {
left: 100px;
}
And my HTML ...
<div id="fader">
<img src="http://dummyimage.com/600x400/000/fff.png&text=Image1"/>
<img src="http://dummyimage.com/200x400/f00/000.jpg&text=Image2"/>
<img src="http://dummyimage.com/100x100/0f0/000.png&text=Image3"/>
<img src="http://dummyimage.com/400x400/0ff/000.gif&text=Image4"/>
<img src="http://dummyimage.com/350x250/ff0/000.png&text=Image5"/>
</div>
Instead of showing one image and fading between the 5 images supplied, it just shows all 5 images at the same time.
I first thought this could be a JQuery problem, so tested to see if JQuery was functioning, which it is.
Here is the original JQuery before I removed whitespaces and swapped $ for JQuery.
$(function() {
$('#fader img:not(:first)').hide();
$('#fader img').css('position', 'absolute');
$('#fader img').css('top', '0px');
$('#fader img').css('left', '50%');
$('#fader img').each(function() {
var img = $(this);
$('<img>').attr('src', $(this).attr('src')).load(function() {
img.css('margin-left', -this.width / 2 + 'px');
});
});
var pause = false;
function fadeNext() {
$('#fader img').first().fadeOut().appendTo($('#fader'));
$('#fader img').first().fadeIn();
}
function fadePrev() {
$('#fader img').first().fadeOut();
$('#fader img').last().prependTo($('#fader')).fadeIn();
}
$('#fader, #next').click(function() {
fadeNext();
});
$('#prev').click(function() {
fadePrev();
});
$('#fader, .button').hover(function() {
pause = true;
},function() {
pause = false;
});
function doRotate() {
if(!pause) {
fadeNext();
}
}
var rotate = setInterval(doRotate, 2000);
});
Thanks in advance!!!!!!!
I love you ;)
Use jQuery or $ and not what you are using.
You are using JQuery, which is wrong.
But if you really want to use JQuery,then you can do the below:
var JQuery = jQuery;
Now, after the assignation, you can use JQuery

Custom jQuery slider for html elements not working

I'm trying to add a slider to animate some paragraphs at my home screen.
I don't want to use any plugin.
I want to create it myself using jQuery. But there is a problem, it seems that condition in jQuery is not working.
Please checkout following codes and try to fix it.
<div id="slider-viewport">
<div class="slider">
<p>1 Cloud based e-commerce solution for your downloadable products</p>
<p>2 Cloud based e-commerce solution for your downloadable products</p>
<p>3 Cloud based e-commerce solution for your downloadable products</p>
<p>4 Cloud based e-commerce solution for your downloadable products</p>
</div>
</div>
CSS
.slider p {
font-size: 25px;
color: #fff;
height: 100px;
margin: 0;
}
#slider-viewport {
width: 100%;
height: 100px;
overflow: hidden;
background-color: black;
}
.slider {
width: 100%;
height: auto;
}
jQuery
$(document).ready(function() {
$('.slider p').first().clone().appendTo('#slider-viewport .slider')
function slider() {
var $slider = $('#slider-viewport .slider');
var currentMargin = $slider.css('margin-top');
var paraHeight = $('.slider p').height();
var setMargin = parseInt(currentMargin) - paraHeight;
var resetMargin = -300;
if (currentMargin < resetMargin) {
$slider.css('margin-top', 0);
};
$slider.animate({
marginTop: setMargin
}, {
duration: 600,
easing: "easeOutQuint"
}
);
};
setInterval(slider, 3000);
});
You can simplify things a bit by animating the first element only and then resetting and putting it back at the end of the list after the animation, also you can avoid setInterval() by making the function recursive
function slider() {
var $slider = $('#slider-viewport .slider');
var $first = $slider.find('p:first');
$first.delay(3000).animate({'margin-top': $first.height() * -1}, 600, "easeOutQuint", function () {
$(this).css('margin-top', 0).appendTo($slider);
slider();
});
};
$(document).ready(function () {
slider();
});
Demo fiddle
var currentMargin = $slider.css('margin-top').split('px')[0];
$slider.css('margin-top', '0px');
Update
$(document).ready(function() {
setInterval(slider, 3000);
});
var $slider = $('#slider-viewport .slider');
var marginNew = $('.slider p').height();
var limit=marginNew*$('.slider p').length;
function slider() {
if(marginNew>=limit)
marginNew=0;
$slider.animate({"margin-top":-marginNew});
marginNew+=100;
};
http://jsfiddle.net/Xh9SM/2/
Fixed Here
http://jsfiddle.net/sk5wq/4/
html code:
<div id="slider-viewport">
<div class="slider">
<p>1 Cloud based e-commerce solution for your downloadable products</p>
<p>2 Cloud based e-commerce solution for your downloadable products</p>
<p>3 Cloud based e-commerce solution for your downloadable products</p>
<p>4 Cloud based e-commerce solution for your downloadable products</p>
</div>
</div>
css code:
.slider p {
font-size: 25px;
color: #fff;
height: 100px;
margin: 0;
}
#slider-viewport {
width: 100%;
height: 100px;
overflow: hidden;
background-color: black;
}
.slider {
width: 100%;
height: auto;
}
update js code:
$(document).ready(function() {
setInterval(initSlider, 3000);
});
function initSlider() {
var slider = $('#slider-viewport .slider'),
sliderMargin = parseInt(slider.css('margin-top')),
pHeight = parseInt(slider.find('p').height()),
sliderGep = '-'+(parseInt(slider.height())-pHeight),
go = 0;
if (sliderMargin <= sliderGep) {
slider.animate({marginTop:pHeight+'px'},0);
go = '0px'
}else{
go = '-='+pHeight+'px'
}
slider.animate({
marginTop: go
}, {
duration: 600,
easing: "easeOutQuint"
});
}

Categories