I have an element:
<b onclick="alert('');" onmouseover="this.style.color='red'; setTimeout('........', 1000);" onmouseout="this.style.color='';">123</b>
I need that when element is mouseovered and after 1 second the mouse cursor continue staying above this element, then onclick() event of this element should start.
In other words, what should be instead of '..............' in onmouseover() event?
window.countdown = setTimeout(function(){this.click();}, 1000);
Additionally, you need to clear the interval in the mouseout handler:
clearTimeout(countdown);
Ideally you would give your element an ID and use the new event registration model:
var e = document.getElementById('myelement');
e.addEventListener('click',function(){
alert('');
});
e.addEventListener('mouseenter',function(){
var self = this;
this.style.color='red';
window.countdown = setTimeout(function(){self.click();}, 1000);
});
e.addEventListener('mouseleave',function(){
this.style.color='';
clearTimeout(countdown);
});
You should start the interval on mouse over event as a global variable to refer on mouse out event to clear it like #Asad said.
<b onclick = "alert()"
onmouseover = "window.countdown = setTimeout(function(){this.click();}, 1000);"
onmouseout = "clearTimeout(countdown)">
123
</b>
You'll have to do some extra work, and this won't work out very well for you inside of inline Javascript. This is all pseudocode so I don't recommend copy/pasting!
// We'll need to create an interval and store it
var timerInterval = {}
// And keep track of how many seconds have elapsed
var timeElapsedInSeconds = 0;
function tick (){
timeElapsedInSeconds++;
if (timeElapsedInSeconds > 0){
// YOUR GREAT CODE HERE
}
// Either way, let's be sure to reset everything.
resetTimer();
}
function hoverOverHandler (){
// Start our timer on hover
timerInterval = window.setInterval(tick, 1000);
}
function resetTimer () {
timeElapsedInSeconds = 0;
window.clearInterval(timerInterval);
}
function hoverOutHandler () {
// Kill timer on hoverout
resetTimer();
}
Ok, I did some trick with dynamic id and this is what came out:
<b style="color:red;" onclick="if(this.style.color!='green'){return false;}else{this.style.color='red';} alert(this.parentNode);" onmouseover="if(this.style.color!='green'){var newID='tmpID_'+Math.floor(Math.random() * (10000000)); if(this.id==''){this.id=newID;} setTimeout('top.document.getElementById(\''+this.id+'\').onclick();',1000); this.style.color='green';}" onmouseout="this.style.color='red';">click</b>
crossbrowsered =)
Related
So, I got an infinite loop to work in this function using setInterval attached to an onClick. Problem is, I can't stop it using clearInterval in an onClick. I think this is because when I attach a clearInterval to an onClick, it kills a specific interval and not the function altogether. Is there anything I can do to kill all intervals through an onClick?
Here's my .js file and the calls I'm making are
input type="button" value="generate" onClick="generation();
input type="button" value="Infinite Loop!" onclick="setInterval('generation()',1000);"
input type="button" value="Reset" onclick="clearInterval(generation(),80;" // This one here is giving me trouble.
setInterval returns a handle, you need that handle so you can clear it
easiest, create a var for the handle in your html head, then in your onclick use the var
// in the head
var intervalHandle = null;
// in the onclick to set
intervalHandle = setInterval(....
// in the onclick to clear
clearInterval(intervalHandle);
http://www.w3schools.com/jsref/met_win_clearinterval.asp
clearInterval is applied on the return value of setInterval, like this:
var interval = null;
theSecondButton.onclick = function() {
if (interval === null) {
interval = setInterval(generation, 1000);
}
}
theThirdButton.onclick = function () {
if (interval !== null) {
clearInterval(interval);
interval = null;
}
}
Have generation(); call setTimeout to itself instead of setInterval. That was you can use a bit if logic in the function to prevent it from running setTimeout quite easily.
var genTimer
var stopGen = 0
function generation() {
clearTimeout(genTimer) ///stop additional clicks from initiating more timers
. . .
if(!stopGen) {
genTimer = setTimeout(function(){generation()},1000)
}
}
}
Live demo
This is all you need!
<script type="text/javascript">
var foo = setInterval(timer, 1000);
function timer() {
var d = new Date();
var t = d.toLocaleTimeString();
document.getElementById("demo").innerHTML = t;
}
$(document).on("click", "#stop_clock", function() {
clearInterval(foo);
$("#stop_clock").empty().append("Done!");
});
</script>
Following code snippet to show the core structure:
EDIT1:
var smthing = 0;
change_name_button.addEventListener('click', function(event){
// some query
// .....
// result from query
data = res.name.coords;
// tried to make the function go to GC
smthing = null;
delete smthing;
smthing = new drawMouseMovement(data);
event.stopPropagation();
}, false);
function drawMouseMovement(data){
// bunch of variables set for drawing function
// .....
// .....
var test = 0;
// draw something to canvas until end "maxLength" is reached
var draw = function() {
if(t < maxLength){
// redraw some stuff to canvas
// .....
}else{
return;
}
}
// function to play pause and replay the drawing on canvas
function playPause(boolPP, boolRP){
if(boolPP){
test = setInterval(draw, 10);
}else{
clearInterval(test);
}
if(boolRP){
// some params being reset
// .....
test = setInterval(draw, 10);
}
}
function play(event){
playPause(true, false);
event.stopPropagation();
}
function pause(event){
playPause(false, false);
event.stopPropagation();
}
function replay(event){
playPause(false, true);
event.stopPropagation();
}
play_button.addEventListener('click', play, false);
pause_button.addEventListener('click', pause, false);
replay_button.addEventListener('click', replay, false);
}
Everytime the change_name_button is clicked drawMouseMovement() is called with new parameters.
Following problem: When the draw function does not reach return before clicking change_name_button again, there are two instances of the same function drawing two different things at the same time. Only the last called instance of the function should be drawing.
I tried deleting the pointer to the function, clearInterval() and removeEventListener. But I don't seem to get any of those to work.
I hope my problem is clear.
Thanks in advance.
EDIT
A simple replication of the problem. Is some_button clicked once, smt is printed every 250ms. Is some_button clicked a second time, smt is printed every 125ms etc. How do I overwrite the first instance of printer() with the next click?
some_button.addEventListener('click', foo, false);
function foo(event) {
printer();
event.stopPropagation();
}
function printer(){
setInterval(function() {
console.log("smt");
}, 250);
}
UPDATE 2
A simple replication of the problem. Is some_button clicked once, smt is printed every 250ms. Is some_button clicked a second time, smt is printed every 125ms etc. How do I overwrite the first instance of printer() with the next click?
No way! Don't kill the function, let it ride. First you need a counter to count the clicks so the function knows it's been clicked the second time. Second, just add extra behavior for when the button is clicked the second time, in this case, you are going to half the time interval.
Ok, when I said JavaScript time is quircky, I meant fu##3d. setInterval needs clearInterval to stop it. What most articles and tutorials fail to say is that the damn setInterval still exists, so making it null will allow you to create a new one. I decided to make a constructor timer.
The demo has a button, click it and it'll print out 'smt' every 2 seconds plus the number of clicks to start a new interval.
The 'Go' button is replaced by a 'Stop' button, once clicked it does as advertised--stops
Click it again and it's the 'Go' button, but this time, it is printing every second now.
Lather, rinse, repeat.
Refactor this demo with some prototype wizardry and you got yourself a class.
PLUNKER - TIMER CONSTRUCTOR
PLUNKER - 1 EVENTLISTENER, MULTIPLE EVENT.TARGETS
SNIPPET
<!DOCTYPE html>
<html>
<head>
<style>
.on { display: block; }
button { display: none; }
</style>
</head>
<body>
<button id="btn1" class="on">Go</button><button id="btn2" class="">Stop</button>
<script>
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
var counter = 0;
var timer = new Timer();
btn1.addEventListener('click', xStart, false);
btn2.addEventListener('click', xStop, false);
function xStart(event) {
timer.term;
counter++;
timer.start(counter);
btn1.classList.toggle('on');
btn2.classList.toggle('on');
event.stopPropagation();
}
function xStop(event) {
timer.term();
btn1.classList.toggle('on');
btn2.classList.toggle('on');
event.stopPropagation();
}
function Timer(c){
var self = this;
self.start = function(c){
var t = self.printer(c);
self.interval = setInterval(function() { self.printer(c); },t);
};
self.term = function(){
self.clear = clearInterval(self.interval);
self.null;
};
self.printer = function(x){
var d = (x % 2 === 0) ? 2 : 1;
var t = 2000 / d;
console.log('smt'+x+' t: '+t);
return t;
};
}
</script>
</body>
</html>
UPDATE 1
The following Plunker demonstrates how you can make the only eventListener the element that your buttons all share as the parent.
PLUNKER
OLD
None of your eventListeners() have anything for capturing phase, although I believe it's false by default, try setting it to false anyways.
change_name_button.addEventListener('click', function(event){
// some query
// .....
// result from query
data = res.name.coords;
// tried to make the function go to GC
smthing = null;
delete smthing;
smthing = new drawMouseMovement(data);
event.stopPropagation();
}, false);
^^^^^^^^====== There is the capturing phase`
Use event.stopPropagation(); on the other eventhandlers as well and place close to the end of handler. Don't forget to pass the (event) object.
function play(event){
playPause(true, false);
event.stopPropagation();
}
function pause(event){
playPause(false, false);
event.stopPropagation();
}
function replay(event){
playPause(false, true);
event.stopPropagation();
}
play_button.addEventListener('click', play, false);
pause_button.addEventListener('click', pause, false);
replay_button.addEventListener('click', replay, false);
Also, if that doesn't fix the issue then you need to post the HTML because the layout of your event.target and event.currentTarget might have to be adjusted.
EDIT
Try changing the if else
function drawMouseMovement(data){
// bunch of variables set for drawing function
// .....
// .....
var test = 0;
// draw something to canvas until end "maxLength" is reached
var draw = function() {
if(t < maxLength){
// redraw some stuff to canvas
// .....
}
// when t has reached maxlength, then it should quit?
return false;
}
I have a series of links with a class "bloglink".
They have a click event associated with them - but that is irrelevant at this point. I am trying to cycle through them and trigger the click event every X seconds. This is where I'm at:
$('a.bloglink').each(function(){
var $bl = $(this);
setInterval(function(){
$bl.trigger('click')
},2000);
})
But it just triggers the click event for all of them at once.
Any tips?
You could do something like this:
(function Loop(){
var arry = $("a.bloglink").get();
var traverse = function(){
$(arry.shift()).trigger('click');
if (arry.length)
setTimeout(traverse, 2000);
};
setTimeout(traverse,2000);
})();
You can see it in action here: http://jsfiddle.net/Shmiddty/B7Hpf/
To start it over again, you can just add an else case:
(function Loop(){
var arry = $("a.bloglink").get();
var traverse = function(){
$(arry.shift()).trigger('click');
if (arry.length)
setTimeout(traverse, 2000);
else
Loop(); // Do the whole thing again
};
setTimeout(traverse,2000);
})();
See here: http://jsfiddle.net/Shmiddty/B7Hpf/1/
Create a function that sets the timer to run your code, clears the timer, then calls itself on the next element...
function processNext($current)
{
$h = setInterval(function() {
$current.css('color', 'green');//do your business here
clearTimeout($h);
if ($current.next('a.blah').size()>0)
{
processNext($current.next('a.blah'));
}
}, 750);
}
processNext($('a.blah').eq(0));
See here: http://jsfiddle.net/skeelsave/6xqWd/2/
So, I got an infinite loop to work in this function using setInterval attached to an onClick. Problem is, I can't stop it using clearInterval in an onClick. I think this is because when I attach a clearInterval to an onClick, it kills a specific interval and not the function altogether. Is there anything I can do to kill all intervals through an onClick?
Here's my .js file and the calls I'm making are
input type="button" value="generate" onClick="generation();
input type="button" value="Infinite Loop!" onclick="setInterval('generation()',1000);"
input type="button" value="Reset" onclick="clearInterval(generation(),80;" // This one here is giving me trouble.
setInterval returns a handle, you need that handle so you can clear it
easiest, create a var for the handle in your html head, then in your onclick use the var
// in the head
var intervalHandle = null;
// in the onclick to set
intervalHandle = setInterval(....
// in the onclick to clear
clearInterval(intervalHandle);
http://www.w3schools.com/jsref/met_win_clearinterval.asp
clearInterval is applied on the return value of setInterval, like this:
var interval = null;
theSecondButton.onclick = function() {
if (interval === null) {
interval = setInterval(generation, 1000);
}
}
theThirdButton.onclick = function () {
if (interval !== null) {
clearInterval(interval);
interval = null;
}
}
Have generation(); call setTimeout to itself instead of setInterval. That was you can use a bit if logic in the function to prevent it from running setTimeout quite easily.
var genTimer
var stopGen = 0
function generation() {
clearTimeout(genTimer) ///stop additional clicks from initiating more timers
. . .
if(!stopGen) {
genTimer = setTimeout(function(){generation()},1000)
}
}
}
Live demo
This is all you need!
<script type="text/javascript">
var foo = setInterval(timer, 1000);
function timer() {
var d = new Date();
var t = d.toLocaleTimeString();
document.getElementById("demo").innerHTML = t;
}
$(document).on("click", "#stop_clock", function() {
clearInterval(foo);
$("#stop_clock").empty().append("Done!");
});
</script>
I am able to find the cursor position. But I need to find out if the mouse is stable. If the mouse wasn't moved for more than 1 minute, then we have to alert the user.
How its possible, are there any special events for this? (Only for IE in javascript)
Set a timeout when the mouse is moved one minute into the future, and if the mouse is moved, clear the timeout:
var timeout;
document.onmousemove = function(){
clearTimeout(timeout);
timeout = setTimeout(function(){alert("move your mouse");}, 60000);
}
Here's a one-and-done function that can check any element for movement:
function mouse (element, delay, callback) {
// Counter Object
element.ms = {};
// Counter Value
element.ms.x = 0;
// Counter Function
element.ms.y = function () {
// Callback Trigger
if ((++element.ms.x) == delay) element.ms.callback(element, element.ms);
};
// Counter Callback
element.ms.callback = callback;
// Function Toggle
element.ms.toggle = function (state) {
// Stop Loop
if ([0, "off"][state]) clearInterval(element.ms.z);
// Create Loop
if ([1, "on"][state]) element.ms.z = setInterval(element.ms.y, 1);
};
// Function Disable
element.ms.remove = function () {
// Delete Counter Object
element.ms = null; return delete element.ms;
};
// Function Trigger
element.onmousemove = function () {
// Reset Counter Value
element.ms.x = -1;
};
// Return
return element.ms;
};
Usage:
mouse(element, delay, callback)
Examples:
Make a video player hide the mouse after 5 seconds when idle and fullscreen
let x = mouse(video, 5000, function (a) {
if (document.webkitIsFullScreen) video.style.cursor = "none";
});
x.toggle(1); addEventListener("mousemove", function () {
video.style.cursor = "auto";
});
Chat Room AFK (45 Seconds) (assuming you have a chat box and a send message function):
let x = mouse(chatBox, (45e3), function (a) {
chatBox.send({ text: chatBox.username + " is AFK.", italic: true });
});
x.toggle(1); x.addEventListener("mousemove", function () {
chatBox.send({ text: chatBox.username + " is no longer AFK", italic: true });
});
Is there not a way to set a timer to start incrementing after every mouse movement event?
If it gets to a minute then pop up the message box, but every time the mouse moves the timer gets reset.
Use a timer that resets its value on mousemove event.
If timer reaches 1 minute --> Do something.
More info on timer here http://www.w3schools.com/js/js_timing.asp
And more info on catchin mouse events here http://www.quirksmode.org/js/events_mouse.html
Yes, you have a onmousemove event in Javascript, so to achieve what you need you just have to do code something like this:
startTimer();
element.onmousemove = stopTimer(); //this stops and resets the timer
You can use it on the document body tag for instance.
UPDATE: #Marius has achieved a better example than this one.
You can use the onmousemove event. Inside it, clearTimeout(), and setTimeout(your_warning, 1 minute).
You could use this script/snippet to detect the mouse pointer position and "remember" it. Then use a timer "setTimeout(...)" to check the position let's say every second and remember that time.
If more than one minute passed and the position hasn't changed, you could alert the user.