I'm working on a mini project where I interview people on short GIF animations. I need to let people see the GIF for 10 seconds and with my code, I've realised that the timer is inaccurate.
I've searched around and found the fix in the Sitepoint article by James Edwards. However its in Javascript and I've been trying to combine the JS and Jquery together but with no success at all.
Here
$(function() {
//when showing image
setTimeout(function() {
$("#div2").fadeOut(0);
}, 10000) //edit timer
$('#btnclick').click(function() {
$('#div2').show();
setTimeout(function() {
$("#div2").fadeOut(0);
}, 10000)
$('#div3').delay(10000).fadeIn(0); //show interview
})
})
The code works fine but I want to implement the self-adjusting mechanism described on Sitepoint. Has anyone done this before or know how I can do this?
The HTML is here:
<div id="div1" class="div1">
<!--Show image button-->
<center>
<input type="button" id="btnclick" value="Show me Image" />
</center>
</div>
<div id="div2" class="main" style="display:none;">
<!--Image-->
<img src="timer.gif"/>
</div>
<div id="div3" class="main" style="display:none;">
<!--Form-->
<form> >
</form>
Thanks in advance.
In jQuery, you can simply use:
$('#myDiv').show();
$('#myDiv').hide();
I believe your fadeIn(0) should work too but fadeIn and fadeOut are doing an animation, and the parameters you're giving it is to do it over 0 millisecond, so it does it instantly but still has to do an animation (which isn't good for your program speed). The best way if you want optimisation is to create a css class like this:
.is-hidden{
display: none;
}
And then do this in jQuery
$('#myDiv').toggleClass('is-hidden');
There's a number of questions in this post, so I'll try to address them one at a time.
jQuery is JavaScript
As a note, jQuery is a library built with JavaScript, so it just provides at convenience methods.
Use .hide() and .show()
What you're probably noticing the most for inaccuracies is probably not related to the fact that the timer is off. Does a few milliseconds make a difference to you? When you set your timeout, you try to fade out the element instantly, but that doesn't happen. After you 10 second timeout, it calls the fade, which takes time. It is likely faster to use .hide() and .show() to hide and show the element.
.delay(10000) is the same as setTimeout( function (){}, 10000)
These two sets are MOSTLY equivalent:
$('#div2').delay(10000).show();
setTimeout( function () {
$('#div2').show();
}, 10000);
The only different is that you're using the jQuery wrapper of the timer. There may be small differences (would have to read the source code), but they should act mostly the same.
Self-adjusting Timer Situation Different?
Your situation is a little different than the self-adjusting timer example you're looking at. In the example, it's an animation that is constantly running shorter tasks on an interval with more granularity, so there's a larger set of time sets to adjust the timeout based on trends. If you're only measuring every 10 seconds, the difference is probably negligible if a user is not creating a lot of samples for your to look at. In my opinion, you'd be better offer just making your code as fast as possible. One would to do that is straight JavaScript to show and hide the div.
var div2 = document.getElementById(id);
// hide
div2.style.display = 'none';
// show
div2
.style.display = 'block';
Related
I know this question has been asked before a lot but I checked most of those and didn't find solution to my problem so I'm asking here again.
So, question is:
I'm working on a cinema website project.
I added a few pictures as slide show in my home page but for some reason, slideshow is not working properly. It has some glitch in it like sometimes order is not correct and sometimes all pictures try to come up at one time or they change super fast etc.
I guessed maybe it's bcz somehow when I reload the website, the previous onlaod also keeps on working so it's like there are 2 slideshows going on or something like that, so from other solutions I guess I have to put onload=null somewhere maybe but I can't figure it out exactly.
Any help would be really appreciated.
This is my html code for slideshow:
<div class="bg-movies" style="top: 65%;">
<img src='images/slideshow/war.jpg' width='1000' height='300'
onload="setSlide();"/>
</div>
And this is my javascript code:
<script language='javascript'>
<!--
var toprated=new Array('sarkar.jpg','hajwala.jpg','96.jpg','war.jpg');
var pos=0,x;
document.images[1].src='images/slideshow/'+toprated[0];
function setSlide(){
x=setInterval('chgPic()',2000);
}
function chgPic(){
pos=(++pos)%toprated.length;
document.images[1].src="images/slideshow/"+toprated[pos];
}
-->
</script>
Your problem is recursion. You are calling the setSlide() method once your image is loaded. This will set up the interval to call the chgPic(), but when the chgPic() method is called and it updates the image src, the onload event on the img tag will be executed again (because an image has been loaded). Therefore setSlide() will be called again which will set up another interval to call the chgPic() method. And on and on etc. I'm surprised your browser hasn't crashed.
What you should do is set up the interval (i.e. call the setSlide() method) once the page has loaded, or even better yet, use jQuery's document ready if you're using jQuery:
$( document ).ready(function()
{
}
And call your setSlide() method in here.
Although, I wouldn't recommend doing it the way you are. You can use some simple jQuery and CSS to get this to work. Take a look at this link.
I want to replay my jquery function ChangeStats() every 5 seconds, it's currently doing sod all.
function ChangeStats() {
$('body').find('.admin-stats-big-figures-hidden').fadeIn(500);
setTimeout(function() {
$('body').find('.admin-stats-big-figures').fadeOut(500);
}, 500);
}
$(document).ready(function(){
setInterval(ChangeStats, 5000);
})();
Yes I have got the right class names.
No I haven't used underscores in my HTML.
I think it's something to do with my use of "find()", once the DOM has loaded and the function is set is it meant to traverse up the DOM tree instead of down?
EDIT:
Updated code, still not working.
HTML:
<span class="admin-stats-big-figures">%productCount%</span>
<span class="admin-stats-big-figures-hidden">hey</span>
Ok, I am going to go out on a limb and make several assumptions here; one is that you wish to cycle between two elements repeatedly, another is that you are using $(this) in the context of the window rather than a containing element. If either of these are incorrect then the following solution may not be suitable. However, let's give this a shot, eh?
1) You need to use setInterval rather than setTimeout to create a repeating call. You can of course "chain" your timeouts (ie: call the succeeding timeout from the code of the current timeout). This has some benefits in certain situations, but for now let's just assume you will use intervals rather than timeouts.
2) You call the find() jQuery method every time, which is a little unnecessary, especially if you will be repeating the actions so one idea would be to cache the lookup. If you are going to do that a custom object would be more suitable than separate global variables.
3) Some flexibility in terms of starting and stopping the animation could be provided. If we use a custom object as mentioned in (2) then that can easily be added.
4) You are using fadeIn and fadeOut, however if you wish the items to cycle then fadeToggle may be your best solution as it will simply allow you to do exactly that, toggle, without needing to check the current opacity state of the element.
5) Finally in my example I have provided a little extra "padding HTML" in order for the example to look good when run. Fading in jQuery will actually set the faded item to a CSS display of "none" which results in the content "jumping about" in this demo, so I have used some div's and a couple of HTML entity spaces to keep the formatting.
Ok, after all that here is the code..
// your custom animation object
var myAnim = {
// these will be cached variables used in the animation
elements : null,
interval : null,
// default values for fading and anim delays are set to allow them to be optional
delay : { fade: 500, anim: 200 },
// call the init() function in order to set the variables and trigger the animation
init : function(classNameOne, classNameTwo, fadeDelay, animDelay) {
this.elements = [$("."+classNameOne),$("."+classNameTwo)];
// if no fade and animation delays are provided (or if they are 0) the default ones are used
if (animDelay) this.delay.anim = animDelay;
if (fadeDelay) this.delay.fade= fadeDelay;
this.elements[0].fadeOut(function(){myAnim.start()});
},
// this is where the actual toggling happens, it uses the fadeToggle callback function to fade in/out one element once the previous fade has completed
update : function() {
this.elements[0].fadeToggle(this.delay.anim,function(el,delay){el.fadeToggle(delay)}(this.elements[1],this.delay.anim));
},
// the start() method allows you to (re)start the animation
start : function() {
if (this.interval) return; // do nothing if the animation is currently running
this.interval = setInterval(function(){myAnim.update()},this.delay.fade);
},
// and as you would expect the stop() stops it.
stop : function () {
if (!this.interval) return; // do nothing if the animation had already stopped
clearInterval(this.interval);
this.interval = null;
}
}
// this is the jQuery hook in order to run the animation the moment the document is ready
$(document).ready(
function(){
// the first two parameters are the two classnames of the elements
// the last two parameters are the delay between the animation repeating and the time taken for each animation (fade) to happen. The first one should always be bigger
myAnim.init("admin-stats-big-figures","admin-stats-big-figures-hidden",500,200);
}
);
OK, so now we need the HTML to compliment this (as I say I have added a little formatting):
<div><span class="admin-stats-big-figures">One</span> </div>
<div><span class="admin-stats-big-figures-hidden">Two</span> </div>
<hr/>
<input type="button" value="Start" onclick="myAnim.start()"/> | <input type="button" value="Stop" onclick="myAnim.stop()"/>
I have also provided buttons to stop/start the animation. You can see a working example at this JSFiddle - although the stop/start buttons are not working (presumably something specific to JSFiddle) they do work when in context though.
Here im gonna just replace your $(this). and maybe it'll work then.. also using callback.
function ChangeStats() {
$('body').find('.admin-stats-big-figures-hidden').fadeIn(500, function() {
$('body').find('.admin-stats-big-figures').fadeOut(500);
});
}
$(document).ready(function(){
setTimeout('ChangeStats()', 5000);
});
I'm trying to do a simple slide out effect, then add a class with display:none;
But for some reason, the jQuery animation is completing instantly, instead of using the duration as the docs say. I tried using different values, and 'slow' / 'fast'.
Looking at the source in Chrome's developer tools, the DOM is updated instantly. Removing the callback doesn't make the animation work either, it just does nothing in that case.
$('.type-panel').slideDown(500, function () {
$(this).addClass('panel-hidden')
});
<div class="ed-panel type-panel">
//bunch of stuff
</div>
What am I missing?
(I have jQuery and jQueryUI referenced)
I think you meant to use .slideUp() to hide it.
$('.type-panel').slideUp(500, function() {
$(this).addClass('panel-hidden');
});
Notice, .slideUp() will add automatically set the display to none.
I have an animation using Animate.CSS that I would like to have replay if the user would like but what I have attempted does not work. Here is the code:
HTML:
<div class="img-center">
<img src="path.jpg" class="feature-image animated rotateInDownRight" />
</div>
<p class="textcenter"> </p>
<div class="img-center">
Replay
</div>
JS:
var $j = jQuery.noConflict();
$j("#replay").click(function() {
$j('.feature-image').removeClass('animated rotateInDownRight').addClass('animated rotateInDownRight');
});
I do know the script itself works as I can see it happen in Firebug however that animation doesn't animate again. How do I achieve this with Animate.CSS?
This is just a guess but it appears that jQuery isn't "finished" removing the class before it adds it back in. I know this makes NO sense, but it's how JavaScript works. It can call the next function in the chain before all the stuff from the first one is finished. I poked around the code on Animate.CSS's site and saw that they use a timeout in their animation function. You might try the same. Here's their code:
function testAnim(x) {
$('#animateTest').removeClass().addClass(x);
var wait = window.setTimeout( function(){
$('#animateTest').removeClass()},
1300
);
}
What this is doing is exactly like what you are doing except that it waits for the animation to finish, then removes the classes. That way when the other class is added back in, it is truely "new" to the tag. Here is a slightly modified function:
function testAnim(elementId, animClasses) {
$(elementId).addClass(animClasses);
var wait = window.setTimeout( function(){
$(elementId).removeClass(animClasses)},
1300
);
}
Notice two things: First this code would allow you to change what element gets the animation. Second, you remove the classes you added after 1300 milliseconds. Still not 100% there, but it might get you further down the road.
It should be noted that if there is already some animation classes on the object it might break this JS.
found the right answer at animate.css issue#3
var $at = $('#animateTest').removeClass();
//timeout is important !!
setTimeout(function(){
$at.addClass('flash')
}, 10);
Actually a simpler version can avoid using JQuery too.
el.classList.remove('animated','flash');
//timeout is important !!
setTimeout(function(){
el.classList.add('animated','flash');
}, 10);
I believe the issue here is that when I remove the class it was adding the class to quickly. Here is how I solved this issue:
(HTML is same as above question).
JS:
var $j = jQuery.noConflict();
window.setTimeout( function(){
$j('.feature-image').removeClass('animated rotateInDownRight')},
1300);
$j("#replay").click(function() {
$j('.feature-image').addClass('animated rotateInDownRight');
});
What I believe is happening is the jQuery code is removing and adding the class to quickly. Regardless of the reason this code works.
If you wish you can also give a try to this javaScript side development that support animate.css animations. Here is an example of usage.
//Select the elements to animate and enjoy!
var elt = document.querySelector("#notification") ;
iJS.animate(elt, "shake") ;
//it return an AnimationPlayer object
//animation iteration and duration can also be indicated.
var vivifyElt = iJS.animate(elt, "bounce", 3, 500) ;
vivifyElt.onfinish = function(e) {
//doSomething ...;
}
// less than 1500ms later...changed mind!
vivifyElt.cancel();
Take a look here
My answer is a trick to add/remove the css class with a tint delay:
$('#Box').removeClass('animated').hide().delay(1).queue(function() {
$(this).addClass('animated').show().dequeue();
});
Also you can test it without hide/show methods:
$('#Box').removeClass('animated').delay(1).queue(function() {
$(this).addClass('animated').dequeue();
});
I fill it works smooth in chrome but it works with more unexpected delay in FF, so you can test this js timeout:
$('#Box').removeClass('animated');
setTimeout(function(){
$('#Box').addClass('animated');
}, 1);
This solution relies on React useEffect, and it's rather clean, as it avoids manipulating the class names directly.
It doesn't really answers the OP question (which seems to be using jQuery), but it might still be useful to many people using React and Animate CSS library.
const [repeatAnimation, setRepeatAnimation] = useState<boolean>(true);
/**
* When the displayedFrom changes, replay the animations of the component.
* It toggles the CSS classes injected in the component to force replaying the animations.
* Uses a short timeout that isn't noticeable to the human eye, but is necessary for the toggle to work properly.
*/
useEffect(() => {
setRepeatAnimation(false);
setTimeout(() => setRepeatAnimation(true), 100);
}, [displayedFrom]);
return (
<div
className={classnames('block-picker-menu', {
'animate__animated': repeatAnimation,
'animate__pulse': repeatAnimation,
})}
...
)
I'm new to javascript so I'm struggling with the basics...
I'm using this delay to bring in a div but i want to fade the div in as part of this function (not just have the box appear)
function show() {
AB = document.getElementById('div_with_text');
AB.style.display = 'inline';
}
setTimeout("show()", 3000);
Can any one help with this?
I've tried adding things like:
$(function(){
$('#div_with_text').fadeIn('slow');
});
but I don't know the language well enough to get it to work...
Any help would be much appreciated!
Is your DIV hidden in the first place? If not, that is your problem. Your are trying to open an already opened door.
Your code is also incorrect, even if you hide the DIV, this will not work. It should have been setTimeout(show, 3000);
With the JavaScript code (setTimeout) you have provided, 3 seconds after the page loads, you are trying to display the DIV. Did you notice that the DIV was already there and never 'appeared' after 3 seconds as you expected?
Example - http://jsfiddle.net/BLPTq/2/ - just click run and see.
To make it work, hide the DIV first and then call the setTimeout or the jQuery method. Example - http://jsfiddle.net/zeXyG/ - just click run and see. Check the CSS display:none;
OR, if you don't want to hide it with CSS, just call hide() before calling fadeIn()
$('#div_with_text').hide().fadeIn('slow');
Example - http://jsfiddle.net/zeXyG/1/
As per your comment below. Add delay() to the call like shown below
$('#div_with_text').hide(); // this or use css to hide the div
$('#div_with_text').delay(2000).fadeIn('slow');
2 seconds after the page loads, this will hide the div and then fade in slowly. Look at this example carefully.
The fadeIn method will only work if you load the jQuery library on your page. Without that, the method will not work since it isn't part of native Javascript.
Once you have loaded jQuery, that method will work as your syntax is correct.