So, I've got this type of situation, but I only want to "Do something" if the user "mouseleave(s)" for more than x amount of time, say one second. How should I implement that?
$("#someElement, #someOtherElement").mouseleave(function() {
// Do something.
});
Later I added:
$('.popover3-test').popover({
placement:'bottom',
template: $('.popover2'),
trigger: 'manual',
}).mouseenter(function(e) {
$(this).popover('show');
$(".popover3-test, .popover2").each(function() {
var t = null;
$(this)
.mouseleave(function() {
t = setTimeout(function() {
$('.popover2').hide();
}, 1000); // Or however many milliseconds
})
.mouseenter(function() {
if(t !== null)
clearTimeout(t);
})
;
});
});
setTimeout should do the trick:
$("#someElement, #someOtherElement").each(function() {
var t = null;
$(this)
.mouseleave(function() {
t = setTimeout(function() {
// Do something.
}, 1000); // Or however many milliseconds
})
.mouseenter(function() {
if(t !== null) {
clearTimeout(t);
t = null;
}
})
;
});
EDIT: If you want it to work on either, just remove the .each:
var t = null;
$("#someElement, #someOtherElement")
.mouseleave(function() {
t = setTimeout(function() {
// Do something.
}, 1000); // Or however many milliseconds
})
.mouseenter(function() {
if(t !== null) {
clearTimeout(t);
t = null;
}
})
;
$("#someElement, #someOtherElement").bind('mouseenter mouseleave', (function() {
var timer;
return function (e) {
if(e.type === 'mouseleave') {
timer = setTimeout(function () {
//do something
}, 1000);
} else {
clearTimeout(timer);
}
};
}()));
EDIT - usable on multiple elements
$("#someElement, #someOtherElement").bind('mouseenter mouseleave', function (e) {
var timer = $(this).data('timer');
if(e.type === 'mouseleave') {
timer = setTimeout(function () {
//do something
}, 1000);
} else {
clearTimeout(timer);
}
$(this).data('timer', timer);
};
});
this might not work as is, but gives you some ideas...
var elapsed = 0;
var timer = setInterval(function(){
elapsed += 20;
if( elapsed >= 1000 ) {
doSomething();
clearInterval(timer);
}
}, 20 );
$('#some').mouseleave(timer);
$('#some').mouseenter(function(){clearInterval(timer);elapsed=0;});
Related
I got a problem that wastes more and more time. Now I want to ask you guys to help me out. I really think it's not a big thing but I can't find the solution:
I have two code snippets, both really similar:
$(function () {
$('.plus--article').on('click', function () {
var $qty = $(this).closest('form').find('input[name="sQuantity"]');
var currentVal = parseInt($qty.val());
if (!isNaN(currentVal)) {
$qty.val(currentVal + 1);
$('.change-quantity--form').submit(function (e) {
var form = this;
e.preventDefault();
var timeout = setTimeout(function () {
$.overlay.open();
form.submit();
}, 2000);
});
}
});
$('.minus--article').on('click', function () {
var $qty = $(this).closest('form').find('input[name="sQuantity"]');
var currentVal = parseInt($qty.val());
if (!isNaN(currentVal) && currentVal > 0) {
$qty.val(currentVal - 1);
window.clearTimeout(timeout);
$('.change-quantity--form').submit(function (e) {
var form = this;
e.preventDefault();
setTimeout(function () {
$.overlay.open({
closeOnClick: false
});
form.submit();
}, 2000);
});
}
});
});
I just want to reset the timeout after a click on one of the buttons.
var time;
}, 2000); use this-> }, time);
$(".test").on("click", function(){
time = 0;
});
I create plugin something like this
timer plugin
(function($) {
$.fn.timer = function(options) {
var defaults = {
seconds: 60
};
var options = $.extend(defaults, options);
return this.each(function() {
var seconds = options.seconds;
var $this = $(this);
var timerIntval;
var Timer = {
setTimer : function() {
clearInterval(timerIntval);
if(seconds <= 0) {
alert("timeout");
}else {
timerIntval = setInterval(function(){
return Timer.getTimer();
}, 1000);
}
},
getTimer : function () {
if (seconds <= 0) {
$this.html("0");
} else {
seconds--;
$this.html(seconds);
}
}
}
Timer.setTimer();
});
};
})(jQuery);
and I call the plugin like this.
$(".myTimer").timer({
seconds : 100
});
i called the plugin at timerpage.php. When i changed the page to xxx.php by clicking another menu, the timer interval is still running and i need to the clear the timer interval.
i created a webpage using jquery ajax load. so my page was not refreshing when i change to another menu.
my question is, how to clear the timer interval or destroy the plugin when i click another menu?
Please try with following modifications:
timer plugin:
(function($) {
$.fn.timer = function(options) {
var defaults = {
seconds: 60
};
var options = $.extend(defaults, options);
return this.each(function() {
var seconds = options.seconds;
var $this = $(this);
var timerIntval;
var Timer = {
setTimer : function() {
clearInterval(timerIntval);
if(seconds <= 0) {
alert("timeout");
}else {
timerIntval = setInterval(function(){
return Timer.setTimer();
}, 1000);
$this.data("timerIntvalReference", timerIntval); //saving the timer reference for future use
}
},
getTimer : function () {
if (seconds <= 0) {
$this.html("0");
} else {
seconds--;
$this.html(seconds);
}
}
}
Timer.setTimer();
});
};
})(jQuery);
Now in some other JS code which is going to change the div content
var intervalRef = $(".myTimer").data("timerIntvalReference"); //grab the interval reference
clearInterval(intervalRef); //clear the old interval reference
//code to change the div content on menu change
For clearing timer associated with multiple DOM element, you may check below code:
//iterate ovel all timer element:
$("h3[class^=timer]").each(function(){
var intervalRef = $(this).data("timerIntvalReference"); //grab the interval reference
clearInterval(intervalRef);
});
Hope this will give an idea to deal with this situation.
Instead of var timerIntval; set the variable timerInterval on the window object, then you will have the access this variable until the next refresh.
window.timerIntval = setInterval(function() {
Then when the user clicks on any item menu you can clear it:
$('menu a').click(function() {
clearInterval(window.timerIntval);
});
Live example (with multiple intervals)
$('menu a').click(function(e) {
e.preventDefault();
console.log(window.intervals);
for (var i = 0; i < window.intervals.length; i++) {
clearInterval(window.intervals[i]);
}
});
(function($) {
$.fn.timer = function(options) {
var defaults = {
seconds: 60
};
var options = $.extend(defaults, options);
return this.each(function() {
if (!window.intervals) {
window.intervals = [];
}
var intervalId = -1;
var seconds = options.seconds;
var $this = $(this);
var Timer = {
setTimer : function() {
clearInterval(intervalId);
if(seconds <= 0) {
alert("timeout");
} else {
intervalId = setInterval(function(){
//Timer.getTimer();
return Timer.getTimer();
}, 1000);
window.intervals.push(intervalId);
}
},
getTimer : function () {
if (seconds <= 0) {
$this.html("0");
} else {
seconds--;
$this.html(seconds);
}
}
}
Timer.setTimer();
});
};
})(jQuery);
$(".myTimer").timer({
seconds : 100
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<menu>
Menu 1
</menu>
<div class="myTimer"></div>
<div class="myTimer"></div>
Just notice that it's little bit risky because you can only run it once otherwise the interval id of the second will override the first.
I'm a PHP developer and I want to make FlipClock's inital value ease-in. I think it can be done by:
Making clock.incerement()'s interval value flexible, Based on how close is current value, to initial value.
Make a break when the current value was equal to initial value.
I changed this code:
var clock;
var initial = 5000;
$(document).ready(function() {
clock = new FlipClock($('.clock'), 0, {
clockFace: 'Counter',
});
setTimeout(function() {
setInterval(function() {
if(clock.getTime().time >= initial) {
clock.stop();
} else {
clock.increment();
}
}, 100);
});
});
to this one:
var clock;
var initial = 5000;
$(document).ready(function() {
clock = new FlipClock($('.clock'), 0, {
clockFace: 'Counter',
});
setTimeout(function() {
setInterval(function() {
if(clock.getTime().time >= initial) {
clock.stop();
} else {
clock.increment();
}
}, function() {
if ((initial - clock.getTime().time) > 1000) {
return 1;
} else if ((initial - clock.getTime().time) > 100) {
return 10;
} else {
return 1000;
}
});
});
});
But did not worked. What i have to do?!
Thank you.
The interval value is supposed to a time in milliseconds, not a function.
One other way to do it is that you calculate the timeout value is as such
setTimeout(function(){
var x = CalculateCurrentInterval(clock);
setInterval(function() {
if(clock.getTime().time >= initial) {
clock.stop();
} else {
clock.increment();
}
}, x);
})
var CalculateCurrentInverval = function(clock) {
if ((initial - clock.getTime().time) > 1000) {
return 1;
} else if ((initial - clock.getTime().time) > 100) {
return 10;
} else {
return 1000;
}
}
I have not tried it but it should work.
Problem is that you are sending in a function where a number is expected
Below is some code that has no jquery, but it is not working:
function start() {
var img = 0,
pic = ['nature', 'grass', 'earth', 'fall2', 'waterfall'],
slider = document.getElementsByClassName('slide_img'),
timerID = 0,
delay = 4000;
function back() {
img--;
if (img <= 0) {
img = pic.length - 1;
}
slider.src = 'pictures/' + pic[img] + '.jpg';
}
function go() {
img++;
if (img >= pic.length) {
img = 0;
}
slider.src = 'pictures/' + pic[img] + '.jpg';
}
document.getElementById('back').onclick = function() {
back();
}
document.getElementById('go').onclick = function() {
go();
}
slider.onmouseenter = function() {
clearTimeout(timerID);
}
document.getElementById('go').onmouseenter = function() {
clearTimeout(timerID);
}
document.getElementById('back').onmouseenter = function() {
clearTimeout(timerID);
}
slider.onmouseleave = function() {
clearTimeout(timerID);
auto();
}
function auto() {
timerID = setTimeout(function () {
go();
auto();
}, delay);
}
auto();
}
Here is what it is in jquery, this one works:
$('document').ready(function() {
var img = 0,
pic = ['nature', 'grass', 'earth', 'fall2', 'waterfall'],
slider = $('img.slide_img'),
timerID = 0,
delay = 4000;
function back() {
img--;
if (img <= 0) {
img = pic.length - 1;
}
slider.attr('src', 'pictures/' + pic[img] + '.jpg');
}
function go() {
img++;
if (img >= pic.length) {
img = 0;
}
slider.attr('src', 'pictures/' + pic[img] + '.jpg');
}
$('button#back').on('click', function() {
back();
});
$('button#go').on('click', function() {
go();
});
$(slider).on('mouseenter', function () {
clearTimeout(timerID);
});
$('button#go').on('mouseenter', function () {
clearTimeout(timerID);
});
$('button#back').on('mouseenter', function () {
clearTimeout(timerID);
});
$(slider).on('mouseleave', function () {
clearTimeout(timerID);
auto();
});
function auto() {
timerID = setTimeout(function () {
go();
auto();
}, delay);
}
auto();
});
What am i doing wrong, why is the first one not working. Im am trying to get rid of jquery so i dont have to include the source file.
You are not executing onload
try
var img = 0,
pic = ['nature', 'grass', 'earth', 'fall2', 'waterfall'],
slider,
timerID = 0,
delay = 4000;
window.onload=function() {
slider = document.getElementsByClassName('slide_img');
document.getElementById('back').onclick = function() {
back();
}
document.getElementById('go').onclick = function() {
go();
}
slider.onmouseover = function() {
clearTimeout(timerID);
}
document.getElementById('go').onmouseover = function() {
clearTimeout(timerID);
}
document.getElementById('back').onmouseover = function() {
clearTimeout(timerID);
}
slider.onmouseout = function() {
clearTimeout(timerID);
auto();
}
auto();
}
function auto() {
timerID = setTimeout(function () {
go();
auto();
}, delay);
}
function back() {
img--;
if (img <= 0) {
img = pic.length - 1;
}
slider.src = 'pictures/' + pic[img] + '.jpg';
}
function go() {
img++;
if (img >= pic.length) {
img = 0;
}
slider.src = 'pictures/' + pic[img] + '.jpg';
}
Use "onmouseover" and onmouseout" for canonical events:
slider.onmouseover = function() {
clearTimeout(timerID);
}
document.getElementById('go').onmouseover = function() {
clearTimeout(timerID);
}
document.getElementById('back').onmouseover = function() {
clearTimeout(timerID);
}
slider.onmouseout = function() {
clearTimeout(timerID);
auto();
}
And don't forget to define "slider" (the initial part is missing in your script):
var slider = document.querySelector('img.slide_img');
<body onload="start"></body>
The JavaScript start doesn't do anything. If you want to call a function, then you need to follow it with ().
This is a rather obtrusive way to deal with event handler assignment though. It is generally preferred to assign such things with JavaScript:
addEventListener('load', start);
See MDN for compatibility notes.
However, you don't have anything in your code that depends on the entire document being loaded. So you can simply:
<script>
start();
</script>
</body>
at the end of your document.
(You can put the whole script there for that matter, and keep it in an external file).
The glowing CSS effect is:
//Public Variables.
var clear_interval;
var stop_set_time_out;
function record_css_effect() {
clear_interval = setInterval(
function() {
rec_block.css('background-color', "red");
stop_set_time_out = setTimeout(function() {
rec_block.css('background-color', "green");
}, 500)
}, 1000);
};
And in another function, I call:
function stop_record() {
alert("Stop record.");
clearTimeout(stop_set_time_out);
clearInterval(clear_interval);
}
The glowing only stops first time.
The second time, I didn't call record_css_effect() function yet the glowing effect happened automatically...
which would mean that the clearTimeout and clearInterval don't work...
Why is that, and How can I achieve it?
UPDATE:
Actually, I use clearInterval( clear_interval ); in many places.
As the user want to take record,they press on a button, and pop_record_window() is then called.
function pop_record_window()
{
$('#start_and_stop_rec').click
(
function(){ record_voice(); }
)
}
function record_voice()
{
record_css_effect();
REC= $("#start_and_stop_rec");
if(REC.prop("value")=="record")
{
alert("Start to record");
alert( dir_path + User_Editime + "/rec"+"/" + "P" + current_page + "_" + records_pages_arr[current_page].get_obj_num() +".mp3");
current_rec_path= dir_path + User_Editime + "/rec"+"/" + "P" + current_page + "_" + records_pages_arr[current_page].get_obj_num() +".mp3";
cur_record_file= new Media(current_rec_path,onSuccess, onError);
cur_record_file.startRecord();
$('#stop_rec').bind("click", function(){
clearTimeout( stop_set_time_out );
clearInterval( clear_interval );
});
REC.prop("value","stop");
}
else if(REC.prop("value") == "stop")
{
stop_record();
cur_record_file.stopRecord();
clearInterval( clear_interval );
//make visibility hidden!
REC.prop("value","record");
}
};
But since the second time, the user didn't press on the button: start_and_stop_rec, the glowing effect fires. However, the code within
if(REC.prop("value")=="record") condition doesn't execute.
If you call record_css_effect() multiple times multiple intervals might start but only the last interval-id will be stored in clear_interval. By ensuring only 1 interval is running at a time you can prevent this from happening.
//Public Variables.
var clear_interval;
var stop_set_time_out;
function record_css_effect() {
if (clear_interval !== null) // if a timer is already returning don't start another
return;
clear_interval = setInterval(function () {
rec_block.css('background-color', 'red');
stop_set_time_out = setTimeout(function () {
rec_block.css('background-color', 'green');
}, 500)
}, 1000);
};
function stop_record() {
alert("Stop record.");
clearTimeout(stop_set_time_out);
clearInterval(clear_interval);
stop_set_time_out = clear_interval = null;
}
You can also make your code a bit simpler (by removing the setTimeout) to make it easier to debug, like so:
//Public Variables.
var clear_interval, isRed = false;
function record_css_effect() {
if (clear_interval !== null) // if a timer is already returning don't start another
return;
clear_interval = setInterval(function () {
if (isRed) {
rec_block.css('background-color', 'red');
isRed = false;
} else {
rec_block.css('background-color', 'green');
isRed = true;
}
}, 500);
};
function stop_record() {
alert("Stop record.");
clearInterval(clear_interval);
clear_interval = null;
}?