How to fade out div when user is inactive - javascript

this should be easy but I just can't get it to work as it should... I have a div element serving as a button. I do not want the button to be visible all the time, just to appear when the user touches the screen (with finger or mouse), stays visible for a period of time (say 2 seconds) after inactivity and then disappear.
I do not want it to disappear 2 seconds after it was made visible (for that I could just use jQuery delay), I want it to disappear 2 seconds after the user has stopped interacting with the screen (i.e. the #grid element in my case). As long as the user is touching the screen or moving the mouse the button is visible, when he stops that activity 2 seconds passes and the button goes away.
The following I have, it does not work:
var grid = $('#grid');
grid.bind('mousemove touchmove tap swipeleft swipeup swipedown swiperight', function(e) {
var timer;
var circle= $('.circle-button');
if (!circle.is(":visible")) {
//button is not visible, fade in and tell it to fade out after 2s
$('.circle-button').fadeIn('slow');
timer = setTimeout(function(){ $('.circle-button').fadeOut('slow') }, 2000);
}
else {
//button is visible, need to increase timeout to 2s from now
if (timer) clearTimeout(timer);
timer = setTimeout(function(){ $('.circle-button').fadeOut('slow') }, 2000);
}
});
Even if the above would work it seems very inefficent to me, to reinitiate a timer for each mousemove (not sure this is a real issue though). If someone could help me with a working, reasonably efficient solution, it would be much appreciated.
Cheers!
--- EDIT -----
Thanks for the replies, they are all good. I ended up using Rohan Veer's suggestion below since it seems the most elegant solution to me, not having to reinitiate a timer at each mouse move.

try this --
<script type="text/javascript">
var idleTime = 0;
$(document).ready(function () {
//Increment the idle time counter every minute.
var idleInterval = setInterval(timerIncrement, 60000); // 1 minute
//Zero the idle timer on mouse movement.
$(this).mousemove(function (e) {
idleTime = 0;
});
$(this).keypress(function (e) {
idleTime = 0;
});
});
function timerIncrement() {
idleTime = idleTime + 1;
if (idleTime > 2) { // 2 minutes
// fade out div
}
}
</script>

You can set a timeout of desire time and on elapse, hide it. Following is a Reference JSFiddle.
Code
var interval = null;
function initInterval(){
if(interval)
clear();
showElement();
interval = setTimeout(function(){
$(".btn").fadeOut();
clear();
},2000);
}
function clear(){
window.clearInterval(interval);
interval = null;
}
function showElement(){
$(".btn").fadeIn();
}
function registerEvents(){
console.log("Events registering");
$(document).on("mousemove", function(){
initInterval();
});
}
(function(){
registerEvents();
})()
.btn{
width:200px;
background:blue;
color:#fff;
padding:5px;
text-align:center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="btn">Will hide in 2 secs</div>

Your code seems pretty close to a working solution, I've made only a couple of slight changes. Pretty much the only way to do this is to set a timer on every move, but also clear the previous timer.
The code below works according to your description.
var timer;
var grid = $('#grid');
grid.bind('mousemove touchmove tap swipeleft swipeup swipedown swiperight', function(e) {
var circle= $('.circle-button');
if (timer) clearTimeout(timer);
if (!circle.is(":visible")) {
circle.fadeIn('slow');
}
timer = setTimeout(function(){ circle.fadeOut('slow') }, 2000);
});
#grid{
width:200px;
height: 100px;
border: 1px solid black
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="grid"></div>
<button class="circle-button">A button</button>

Related

How to freeze Javascript timeouts and BS4/jQuery animations?

I have an HTML page that has timeouts. I want to freeze them when you press a button (#pauseButton) and then resume when you press it again, preferably freezing all BS4 and jQuery animations also.
<button id="pauseButton"></button>
<script>
$(document).ready(function(){
setTimeout(function() {
alert("This is an alert")
},10000);
$("#pauseButton").click(function(){
// Pause timeouts and page
});
});
</script>
EDIT
I have been notified that there is a possible duplicate answer, so I am now focusing on pausing animations and other page elements.
That answer shows how to pause timeouts only.
There are many ways to solve this issue. Many of them are mentioned in this question as mentioned by #EmadZamout in the comments.
But, if you are looking for an easy and maybe an alternate way to solve this. Try this. Here I am using requestAnimationFrame to solve the issue
let ran = Date.now(); // contains the last updated time
let time = 0; // time in seconds
let paused = false; // store the state
const func = () => {
if (!paused && Date.now() - ran > 1000) {
time++;
ran = Date.now();
console.log('now')
}
if (time === 8)
return alert('This works!');
requestAnimationFrame(func);
}
func();
document.querySelector('button').addEventListener('click', () => paused = !paused);
<button>Change state</button>
For stopping all the animations of the website, you need to manually stop each animation.
For stopping a jQuery animation, you can use .stop() helper. An example:
let paused = false; // state of the animation
let dir = 'down'; // to store the direction of animation so that the next time continues in the correct direction
let timeDown = 2000; // to animate properly after resuming
let timeUp = 2000; // to animate properly after resuming
// the initial calling of the animation
(function() {
slideDown();
})();
// function which resumes the animation
function animate() {
switch (dir) {
case 'up':
slideUp();
break;
case 'down':
slideDown();
break;
}
}
// a function to animate in the uppward direction
function slideUp() {
dir = 'up'; // setting direction to up
timeDown = 2000; // resetting the duration for slideDown function
$('div').stop().animate({
left: 0
}, {
duration: timeUp,
complete: slideDown, // calling slideDown function on complete
progress: function (animation, progress, ms) {
timeUp = ms; // changing the duration so that it looks smooth when the animation is resumed
}
}); // actual animation
}
// a function to animate in the downward direction
function slideDown() {
dir = 'down'; // setting direction to down
timeUp = 2000; // resetting the duration for slideDown function
$('div').stop().animate({
left: 200
}, {
duration: timeDown,
complete: slideUp, // calling slideUp function on complete
progress: function (animation, progress, ms) {
timeDown = ms; // changing the duration so that it looks smooth when the animation is resumed
}
}); // actual animation
}
// button click event listener
$('button').click(function() {
if (paused)
animate(); // to resume the animation
else
$('div').stop(); // to stop all the animations on the object
paused = !paused; // toggling state
});
div {
position: relative;
width: 100px;
height: 100px;
background: dodgerblue;
}
<button>Pause</button>
<div></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
For bootstrap, I don't think you have any bootstrap animations which needed to be paused in this scenario which you have mentioned since bootstrap animations depend on user interactions. If you want to prevent user interaction, you can put an overlay over the website says "Paused". Or, if you don't want to do that you can use CSS property pointer-events: none to disable all the pointer events.
Now for CSS animations, you can set a property called animation-play-state to paused.
If you want to change the state of the animations to paused when the user is not on the page (As I understood for your updated questions) you can use the new visibilityState API for that. There is an event visibilitychange which is fired when there a change in visibility.
document.addEventListener("visibilitychange", function() {
console.log( document.visibilityState );
document.querySelector('div').innerHTML = document.visibilityState;
});
<div>
Try opening a different tab or change the focus to another app
</div>

setInterval executions too fast

There is so many good post regarding this question after their own case, but i cannot find any good answer in my case.
I have a multiple setInterval in different files which serves on their own functions:
The application is a slide show directory, and i have one main setInterval which process the cycle of a custom slideshow in the main app.
mainInterval = setInterval(changeSlide, 20000); execute after 20 seconds
function changeSlide(){
// .... do changes
}
The other one serves as a idle timer when customer click on the information of a slide a modal will appear but when the there is no user interaction the modal will close. This function reside in another javascripts file.
$('.item').click(function(e){
// .. show modal
idleInterval = setInterval(timerIncrement, 1000); // executes every 1 secs.
});
// This will reset idleTime when user interact with mousemove
$(this).mousemove(function (e) {
idleTime = 0;
});
// This will reset idleTime when user interact with keypress.
// Since there is a side panel search engine will appear
// when a button search is clicked.
$(this).keypress(function (e) {
idleTime = 0;
});
function timerIncrement() {
idleTime = idleTime + 1; // increment whenever the function is called
// idleTime is more than 10 secs?
// If true (10 secs is met) close the search panel if open
// and close the modal.
if (idleTime > 10) {
// ... close the search panel if open
// ... hides modal
clearInterval(idleInterval);
}
}
UPDATE
Since there is a modal will show when .item is click and in order to avoid multiple setInterval.
I handle the clearInterval(IdleInterval) when modal hides event triggered.
$('#item-modal').on('hide.uk.modal', function(e){
clearInterval(idleInterval);
});
Now the biggest problem is the modal closes before actual 10 seconds is met, when i print the console.log(idleTime); bang! i saw the timer executes faster than normal.
You have not reset the interval every time the .item is clicked which may have caused an issue with multiple intervals running
// explicitely save the state you will be modifying to the window
var idleInterval = null
var idleTime = 0
$('.item').click(function(e) {
// clear the interval if it's set
clearInterval(idleInterval)
idleInterval = setInterval(timerIncrement, 1000);
});
var resetIdleTime = function(e) {
idleTime = 0;
}
$(this)
.mousemove(resetIdleTime)
.keypress(resetIdleTime);
function timerIncrement() {
idleTime = idleTime + 1;
console.log(idleTime)
if (idleTime > 2) {
alert('show modal')
clearInterval(idleInterval);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="item">this is the item</div>

Why doesn't my mouseOver functions work?

The game is quite simple you click on the start button to begin then move your mouse along the track until you reach the end then the timer stops and shows you the score. If you go out of the track you get a score of zero.
Why don't my mouseOver functions work?
Link to my full code: http://www.codecademy.com/TictacTactic/codebits/AQBK4L/edit
Thank you in advance!
var score = 1000;
var timer = setInterval(countDown(), 1000);
$(document).ready(function() {
$('#start').click(function() {
$('#game').mouseover(function() {
stopTimer();
score = 0
$('#points').html(score)
});
$('#end').mouseover(function() {
stopTimer()
$('#points').html(score)
});
});
});
function countDown() {
score = score - 1;
}
function stopTimer() {
clearInterval(timer);
}
Most events are in lowercase, like mouseover, mouseout etc. There are also others that have capitals, like DOMContentLoaded. Most (if not all) programming languages are case-sensitive, watch out for these.
Try this
var clicked = false;
$('#start').click(function() {
if(!clicked){
clicked = true;
}
});
$("#game").hover(function(){
if(clicked){
stopTimer();
score = 0;
$("#points").html(score);
}
});
$("#end").hover(function(){
if(clicked){
stopTimer();
$("#points").html(score);
}
});
Then later if you don't want the hover event to work just set clicked to false I.E : clicked = false;

jQuery Rotate prevent stacking function after a click

fiddle link
Hello,
I am using this jQueryRotate plugin to rotate my div's after a user clicks on the button.
I would like to stop stacking the rotation after the button is clicked more than once. It just keeps on speeding up.
I have researched it and using .stop() nor return false; wont help.
All I want is to know, whether there is a way to reset the rotation on the next click, or stop it after clicking on another button.
Thanks a lot!
The glitch came from having the declaration multiple times in the loop.
I pulled the variables outside the click event which stopped the glitch.
To prevent the speed increasing, i did a quick check to see if the button had already been clicked. See below
$(document).ready(function () {
var angle = 0
var angleone = 0;
var clicked = false;
$('.concept').click(function () {
if (!clicked) {
setInterval(function () {
angle += 3;
$(".gear").rotate(angle);
}, 50);
setInterval(function () {
angleone -= 3;
$(".gear-one").rotate(angle);
}, 50);
clicked = true;
}
});
$('.bar').click(function () {
if ($('#default').is(':visible')) {
$('#default').fadeOut(200);
};
});
});

starting and stopping a timer with jquery in hover

how would you guys reinitiate a javascript timer after it's been stopped. Basically I need the timer to stop, and then start again on rollout of a div. I have
var timer = setInterval(myFunction, 1000);
timer
function myFunction(){<br/>
if(){
do this
}
else if () {
do this
}
};
then I have
$("td").hover(
function () {
window.clearInterval()
},<br/>
function () {
timer
}
);
all works good except it doesn't start again on hover off. If I put a new timer in hover off the timer starts to speed up every time you hover on and off.... Any ideas.
Thanks
var intervalID = setInterval(myFunction, 1000);
function myFunction(){
//logic goes here
};
$("td").hover( function () {
window.clearInterval(intervalID)
},
function () {
intervalID = setInterval(myFunction, 1000);
} );
Explanation: What's happening is that the setInterval is returning the ID associated with that interval.
I did a littse jsFiddle to show it works.
NOTE: this doesn't pause the current Interval. It stops it and starts it again. So if you were in a 10sec interval at 9 secs and stopped it. When it starts again it will take another 10secs.

Categories