I am making a website which performs some calculations and then plots a graph. Now what I want is when the computation is going on, it should show a loading animation and when the calculations are done, that animation should disappear.
P.S. It has nothing to do with page loading so I guess page loader is not an option.
document.getElementById("submitButton").onclick=function()
{
document.getElementById("loader").style.display='flex'; //this is the animation div
const permutationGeneration = (arr = []) => {
let res = []
const helper = (arr2) => {
if (arr2.length==arr.length)
return res.push(arr2)
for(let e of arr)
if (!arr2.includes(e))
helper([...arr2, e])
};
helper([])
delete result;
return;
};
var randArray=Array.from({length : size}, () => Math.floor(Math.random() * 100000));
timeReq = new Date().getTime();
permutationGeneration(randArray);
timeReq = ((new Date().getTime()) - timeReq)/1000;
}
This is the code snippet, now when permutation generation is going on, I want a loading animation.
When I click submit button, display changes from 'none' to 'flex'. Now how to change display back to none, when calculation is done & graph is plotted.
One way you can do it is with setTimeout which sets a timeout before something happens. For example, in this code down here, it loads and gif which is loading gif. After 2-3 seconds, the results go from display:none to display:block; and vice versa with the gif. It shows for 2 seconds, and after that timeout, it gets a style of display:none.
// Listen for submit
document.getElementById('loan-form').addEventListener('submit', function(e){
// Hide results
document.getElementById('results').style.display = 'none';
// Show loader
document.getElementById('loading').style.display = 'block';
setTimeout(calculateResults, 2000);
e.preventDefault();
});
Related
I'm trying to achieve an effect where the javascript detects whether the user has stopped scrolling/hovering over the page, and slowly shows a piece of text over the page, sort of like a paywall. The effect I'm trying to achieve is a simplified version of this website where when the user is inactive for a certain amount of time, eyes start to appear on the page
You can use setTimeout and clearTimeout to perform an action when the mouse stops moving. Here the text would reappear after 3 seconds of inactivity
var timeout;
var element = document.getElementById("element");
document.addEventListener("mousemove", function(e) {
element.style.opacity = 0;
clearTimeout(timeout);
timeout = setTimeout(function() {
element.style.opacity = 1;
}, 2000);
});
#element {
transition: opacity 0.5s;
opacity 0;
}
<div id="element">I see you<div>
First, you want to define what it means for a user to be "inactive". For example, we can consider a user to be inactive if they haven't moved their mouse or scrolled for 30 seconds. When that happens, we want to fire off some other code to signal that the user has gone inactive.
const addUserInactiveListener = (
onUserInactive,
inactiveTimeMs = 30000
) => {
let timeout = setTimeout(onUserInactive, inactiveTimeMs);
const onUserAction = () => {
clearTimeout(timeout);
timeout = setTimeout(onUserInactive, inactiveTimeMs);
}
document.addEventListener('mousemove', onUserAction);
document.addEventListener('scroll', onUserAction);
}
// console log after 5s of inactivity
addUserInactiveListener(() => console.log('inactive'), 5000)
I'm fairly new to jQuery and I'm currently working on a slideshow.
The slideshow consists of a number of headers that plays automatically and shows an image that belongs to a specific header. The moment you hover over a title as a user, the slideshow stops playing automaticly and you have the control over the view.
The problem I encounter is that sometimes after mouseout(); the slideshow shows the wrong image. I would like the slideshow to continue from where it left off.
I have tried several things including this example: Stop loop on hover
Which is basically what I am looking for. Unfortunately I'm not yet skilled enough to apply this myself in jQuery or understand this particular code. I know I have to keep track of the loop in some way...
All help and tips are welcome, thanks!
var autoPlay = 0;
$(function() {
myCarousel();
$(".indexTitle").mouseenter(pauseCarousel);
$(".indexTitle").mouseout(playCarousel);
});
function myCarousel() {
var x = $(".indexTitle");
var n = $(".indexImage");
for (i = 0; i < x.length; i++) {
$(x[i]).removeClass("redStroke");
$(n[i]).removeClass("showIndexImage");
}
autoPlay++;
if (autoPlay > x.length && n.length) {
autoPlay = 1
}
$(x[autoPlay - 1]).addClass("redStroke");
$(n[autoPlay - 1]).addClass("showIndexImage");
myTimeOut = setTimeout(myCarousel, 2000); // Change image every 2.5 seconds
}
function pauseCarousel() {
console.log("Enter = Pause");
clearTimeout(myTimeOut);
$(".indexTitle").removeClass("redStroke");
$(".indexTitle").removeClass("showIndexImage");
};
function playCarousel() {
console.log("Exit = Play");
setTimeout(myTimeOut);
myCarousel();
};
My Fiddle: https://jsfiddle.net/L_03k/830adhfp/35/
I'm a little lost. I have used this JSFiddle code regarding a solution to my problem. http://jsfiddle.net/f8d1js04/2/ (thank you MartinWebb) - and the question(for context) is posed here; Add Fade Effect in Slideshow (Javascript) - MartinWebb's solution is towards the bottom.
Essentially I am rendering a slider onto the page. Now when I put random image links into the imgArray on the JSFiddle, it behaves perfectly. However, when I do it on my page and in my files (in the dom), after the last image, there is a gap - time w/ no image showing, and then it continues to run. How do I get rid of this momentary gap?
Also any ideas on what could be causing this to happen on the browser instead of the JSFiddle?
Sincerely thank you for any help & assistance!
var curIndex = 0,
imgDuration = 3000,
slider = document.getElementById("slider"),
slides = slider.childNodes; //get a hook on all child elements, this is live so anything we add will get listed
imgArray = [
'http://placehold.it/300x200',
'http://placehold.it/200x100',
'http://placehold.it/400x300'];
//
// Dynamically add each image frame into the dom;
//
function buildSlideShow(arr) {
for (i = 0; i < arr.length; i++) {
var img = document.createElement('img');
img.src = arr[i];
slider.appendChild(img);
}
// note the slides reference will now contain the images so we can
access them
}
//
// Our slideshow function, we can call this and it flips the image instantly, once it is called it will roll
// our images at given interval [imgDuration];
//
function slideShow() {
function fadeIn(e) {
e.className = "fadeIn";
};
function fadeOut(e) {
e.className = "";
};
// first we start the existing image fading out;
fadeOut(slides[curIndex]);
// then we start the next image fading in, making sure if we are at the end we restart!
curIndex++;
if (curIndex == slides.length) {
curIndex = 0;
}
fadeIn(slides[curIndex]);
// now we are done we recall this function with a timer, simple.
setTimeout(function () {
slideShow();
}, imgDuration);
};
// first build the slider, then start it rolling!
buildSlideShow(imgArray);
slideShow();
I have created a newsfeed. The feed switches every 2 seconds. You can also manually switch left/right, or click the panel from the squares at the bottom. The switching between slides is down using jQuery UI Slide.
Right now, if you are in the middle of a slide, and you click left/right/squares, then another slide occurs on top of the existing, still going slide and the whole system is messed up.
How can I prevent other actions occurring if a slide/switch is already in progress?
This is my code:
$(document).ready(function(){
newsfeedTimer = setInterval(newsfeed, displayDuration);
// Manual change of feed (LEFT)
$('#newsfeeds_wrapper > .left').click(function(event){
event.stopPropagation();
feedLeft();
clearInterval(newsfeedTimer);
newsfeedTimer = setInterval(newsfeed, displayDuration);
});
// Very similar code for feed right
// Ignore the other method of switching (if it works for above, I can implement it for this one)
});
function newsfeed() {
feedRight();
}
// Feed to the Right
// jump is used to jump multiple newsfeed instead of one at a time
function feedRight(jump)
{
jump = typeof jump !== 'undefined' ? jump : 1;
var current = $('.newsfeed:first');
var next = $('.newsfeed:nth(' + jump + ')');
current.hide('slide',{duration: transitionDuration}, function(){
// Append as many needed
for( var i = 0; i < jump; i++ ) {
$('.newsfeed:first').appendTo('#newsfeeds');
}
next.show('slide',{direction : 'right' , duration: transitionDuration});
}
I don't want to stop() an animation! I want to disable changing the slides IF there is animation happening!!
without seeing the full breadth of the code, I am shooting myself in the foot here. But here is a direction I would take it. You could also have two functions, one to bind, another to unbind. When animation is initiated, you unbind the left/right controls. When stopped, you bind. Or, set a global variable... ala.
var config = {'inProgress': false};
$('#newsfeeds_wrapper > .left').click(function(event){
if(!config.inProgress){
event.stopPropagation();
feedLeft();
clearInterval(newsfeedTimer);
newsfeedTimer = setInterval(newsfeed, displayDuration);
}
});
in your animation function. Seems like when you cut/paste, some of the code is lost, so lets just assume some animation.
when you enter your animation functions, set config.inProgress = true;
function feedRight(jump)
{
config.inProgress = true;
// removed your code, but just using for simplicity sake
// added a callback
next.show('slide',{direction : 'right' , duration: transitionDuration},
function() {
// Animation complete. Set inProgress to false
config.inProgress = false;
});
)
}
So I've created the following function to fade elements in and passed in a div that I want to fade in which in this case is an image gallery popup that I want to show when a user clicks an image thumbnail on my site. I'm also passing in a speed value (iSpeed) which the timeout uses for it's time value. In this case I'm using 25 (25ms).
I've stepped through this function whilst doing so it appears to be functioning as expected. If the current opacity is less than 1, then it is incremented and it will recall itself after the timeout until the opacity reaches 1. When it reaches one it stops fading and returns.
So after stepping through it, I take off my breakpoints and try to see it in action but for some reason my gallery instantly appears without any sense of fading.
var Effects = new function () {
this.Fading = false;
this.FadeIn = function (oElement, iSpeed) {
//set opacity to zero if we haven't started fading yet.
if (this.Fading == false) {
oElement.style.opacity = 0;
}
//if we've reached or passed max opacity, stop fading
if (oElement.style.opacity >= 1) {
oElement.style.opacity = 1;
this.Fading = false;
return;
}
//otherwise, fade
else {
this.Fading = true;
var iCurrentOpacity = parseFloat(oElement.style.opacity);
oElement.style.opacity = iCurrentOpacity + 0.1;
setTimeout(Effects.FadeIn(oElement, iSpeed), iSpeed);
}
}
}
Here's where I'm setting up the gallery.
this.Show = function (sPage, iImagesToDisplay, oSelectedImage) {
//create and show overlay
var oOverlay = document.createElement('div');
oOverlay.id = 'divOverlay';
document.body.appendChild(oOverlay);
//create and show gallery box
var oGallery = document.createElement('div');
oGallery.id = 'divGallery';
oGallery.style.opacity = 0;
document.body.appendChild(oGallery);
//set position of gallery box
oGallery.style.top = (window.innerHeight / 2) - (oGallery.clientHeight / 2) + 'px';
oGallery.style.left = (window.innerWidth / 2) - (oGallery.clientWidth / 2) + 'px';
//call content function
ImageGallery.CreateContent(oGallery, sPage, iImagesToDisplay, oSelectedImage);
//fade in gallery
Effects.FadeIn(oGallery, 25);
}
Could anyone help me out?
Also, I'm using IE10 and I've also tried Chrome, same result.
Thanks,
Andy
This line:
setTimeout(Effects.FadeIn(oElement, iSpeed), iSpeed);
calls Effects.FadeIn with the given arguments, and feeds its return value into setTimeout. This is exactly like foo(bar()), which calls bar immediately, and then feeds its return value into foo.
Since your FadeIn function doesn't return a function, that would be the problem.
Perhaps you meant:
setTimeout(function() {
Effects.FadeIn(oElement, iSpeed);
}, iSpeed);
...although you'd be better off creating that function once and reusing it.
For instance, I think this does what you're looking for, but without recreating functions on each loop:
var Effects = new function () {
this.FadeIn = function (oElement, iSpeed) {
var fading = false;
var timer = setInterval(function() {
//set opacity to zero if we haven't started fading yet.
if (fading == false) { // Consider `if (!this.Fading)`
oElement.style.opacity = 0;
}
//if we've reached or passed max opacity, stop fading
if (oElement.style.opacity >= 1) {
oElement.style.opacity = 1;
clearInterval(timer);
}
//otherwise, fade
else {
fading = true;
var iCurrentOpacity = parseFloat(oElement.style.opacity);
oElement.style.opacity = iCurrentOpacity + 0.1;
}
}, iSpeed);
};
};
Your code has a lot of problems. The one culpable for the element appearing immediately is that you call setTimeout not with a function but with the result of a function, because Effects.FadeIn will be executed immediately.
setTimeout(function(){Effects.FadeIn(oElement, iSpeed)}, iSpeed);
will probably act as you intend.
But seriously, you probably should not re-invent this wheel. jQuery will allow you to fade elements in and out easily and CSS transitions allow you to achieve element fading with as much as adding or removing a CSS class.
T.J. and MoMolog are both right about the bug: you're invoking the Effects.FadeIn function immediately before passing the result to setTimeout—which means that Effects.FadeIn calls itself synchronously again and again until the condition oElement.style.opacity >= 1 is reached.
As you may or may not know, many UI updates that all take place within one turn of the event loop will be batched together on the next repaint (or something like that) so you won't see any sort of transition.
This jsFiddle includes the suggested JS solution, as well as an alternate approach that I think you may find to be better: simply adding a CSS class with the transition property. This will result in a smoother animation. Note that if you go this route, though, you may need to also include some vendor prefixes.