Keep calling on a function while mouseover - javascript

how do I keep calling a function on mouseover while the mouse is hovered over an html element
Example:
<script>
function a() {
"special code hear"
}
</script>
<div onmouseover( 'a()')> </div>
How can I keep calling the function a while the mouse is hovered over the div instead of having it call the function once.

Events don't repeat automatically. You can use a timer to repeat the command while the mouse is over, but don't forget to stop the timer at the onmouseout event. You'll need a variable outside of the functions to track the timer so it can be cancelled, which is why we have var repeater declared separately.
<script>
var repeater;
function a() ...
</script>
<div onmouseover="repeater=setInterval(a(), 100);" onmouseout="clearInterval(repeater);"></div>

Here is one possible solution using setTimeout (DEMO HERE), it will be repeated every second:
HTML CODE:
<div id='div'>test</div>
JS code :
<script>
document.getElementById('div').onmouseover=function(){a();};
function a(){
//some code here
setTimeout(a,1000);
}
</script>

TRY THIS FIDDLE
http://jsfiddle.net/C4AVg/
var pee = '';
$('#poop').mouseover(function(){
pee = setInterval(function() {
      // Do something every 5 seconds
alert('hi');
}, 1000);
});
$('#poop').mouseout(function() {
clearInterval(pee);
});

As others already mentioned calling a function repeatedly can be achieved using setInterval and stopping it can be done using clearInterval.
In case you're looking for a general solution you could use something like this:
function repeatWhileMouseOver(element, action, milliseconds) {
var interval = null;
element.addEventListener('mouseover', function () {
interval = setInterval(action, milliseconds);
});
element.addEventListener('mouseout', function () {
clearInterval(interval);
});
}
This starts the interval when the mouse is over the element and will call the action function every milliseconds. When the mouse leaves the element the repeated action will be stopped (until you hover the element again).
Just to show a simple application that counts the accumulated (complete) seconds you hovered an element:
function repeatWhileMouseOver(element, action, time) {
var interval = null;
element.addEventListener('mouseover', function() {
interval = setInterval(action, time);
});
element.addEventListener('mouseout', function() {
clearInterval(interval);
});
}
var counter = 1;
function count() {
console.log(counter++);
}
repeatWhileMouseOver(document.getElementById('over'), count, 1000);
#over {
border: 1px solid black;
}
<span id="over">Hover me (at least one second)!</span>
When you run the snippet note that it stops counting when you leave the element, but it resumes counting when you hover it again.
Maybe important to note that mouseout could also be replaced with mouseleave and similarly for mouseover and mouseenter. They will behave different if the element you attach the handler to has child elements.
Just a note about compatibility:
addEventListener is not supported in Internet Explorer 8 and before (see this Q+A for workarounds).
The mouseenter and/or mouseleave event are not supported (or supported correctly) in several old browsers. Check the notes about compatibility in case you have to support these (see for example this Q+A).

<script type="text/javascript">
var tId = null,
time = 100;
$( '#test' ).hover(
function( event ) {
tId = setTimeout( function() {
}, time);
},
function( event ) {
clearTimeout( tId );
}
)
</script>
<div id="test">test</div>

You should use setInterval() function here...
it also gives you the power to call the function in whatever time interval you desire
like: setInterval("a()",1000);
here the time is 1/1000 of a second so 1000 means 1 second
you can put this setInterval function in any function say b() and call the b() function from the div tag:
<div onmouseover="b()">

//
// try the timer factory
//
function timer ( callbacks, delay, fireNTimes ) {
timer._cb ||
( timer._cb = function () { return true; } );
return (function ( callbacks, delay, fireNTimes ) {
var
un,
timerState = {
'current-count' : 0,
'delay' : Math.abs( parseFloat( delay ) ) || 1000,
'repeat-count' : Math.abs( parseInt( fireNTimes ) ) || Number.POSITIVE_INFINITY,
'running' : false,
'interval' : un
},
callback = {
onTimer: callbacks.onTimer || timer._cb,
onStart: callbacks.onStart || timer._cb,
onStop : callbacks.onStop || timer._cb,
onEnd : callbacks.onEnd || timer._cb
};
return {
ctx: this,
startargs: [],
start: function ( /* callbacks_context, ...params */ ) {
var
that = this,
args = Array.prototype.slice.call( arguments, 1 );
( arguments[0] !== un ) && ( this.ctx = arguments[0] );
( args.length != 0 ) && ( this.startargs = args );
this.running() || (
timerState.running = true,
callback.onStart.apply( this.ctx, this.startargs ),
timerState['current-count'] += 1,
callback.onTimer.apply( this.ctx, this.startargs ),
( timerState['current-count'] == timerState['repeat-count'] ) &&
(
callback.onEnd.apply( this.ctx, this.startargs ),
( timerState["current-count"] = +( timerState.running = false ) ), true
) ||
( timerState.interval =
window.setInterval( function () {
timerState['current-count'] += 1;
callback.onTimer.apply( that.ctx, that.startargs );
( timerState['current-count'] == timerState['repeat-count'] ) &&
that.reset() &&
callback.onEnd.apply( that.ctx, that.startargs );
}, timerState.delay
)
)
);
return this;
},
stop: function () {
this.running() &&
(
window.clearInterval( timerState.interval ),
timerState.interval = un,
timerState.running = false,
callback.onStop.apply( this.ctx, this.startargs )
);
return this;
},
reset: function () {
return this.running() &&
( ! ( timerState["current-count"] = +( timerState.running = false ) ) ) &&
( window.clearInterval( timerState.interval ), true ) &&
( ( timerState.interval = un ), this );
},
currentCount: function () {
return timerState['current-count'];
},
delay: function () {
return timerState.delay;
},
repeatCount: function () {
return timerState['repeat-count'];
},
running: function () {
return timerState.running;
}
};
})( callbacks, delay, fireNTimes );
}
var
tm = timer(
{
onStart : function () { console.log( 'start:', 'this === ', this, arguments ); },
onTimer : function () { console.log( 'timer:', 'this === ', this, arguments ); },
onEnd : function () { console.log( 'done:', 'this === ', this, arguments ); },
onStop : function () { console.log( 'pause:', 'this === ', this, arguments ); }
},
2000
),
el = document.getElementById('btn1'),
o = { p1:'info' };
el.onmouseover = function () { tm.start( el, o ); };
el.onmouseout = function () { tm.stop(); };
//
//
// start: this === <button id="btn1"> [Object { p1="info"}]
// timer: this === <button id="btn1"> [Object { p1="info"}]
// timer: this === <button id="btn1"> [Object { p1="info"}]
// timer: this === <button id="btn1"> [Object { p1="info"}]
// pause: this === <button id="btn1"> [Object { p1="info"}]
//
// etc...
//
//

I think what you're looking for is actually the onmousemove event, it's a cleaner way to access the event object while you hover some element.
<script>
function a() {
"special code hear"
}
</script>
<div onmousemove( 'a()')> </div>
onmousemove event is called while you're hovering the element, check this example from W3 School.
And to understand more about this event, Mozilla docs covers much info about it.

Related

One button to fire toggle functions? Press button -> toggleOn(), press again -> toggleOff(), press again -> toggleOn()

Is it possible to use the same onClick from a button to make it a "toggle"?
I have a button, <button>Toggle</button> and basically toggling it on should execute either toggleOn() or toggleOff().
How do I do this with just onClick property?
Here is a simple "toggler" higher-order function:
function toggler(fn1, fn2) {
var toggled = true;
return function () {
toggled = !toggled;
return (toggled ? fn1 : fn2).apply(this, arguments);
}
}
function logToConsole (e) {
console.log(this, e);
}
function logToAlert (e) {
alert(e);
}
var toggledLog = toggler(logToConsole, logToAlert);
Now running toggledLog with arguments and context will work properly. You can use it in your onClick handler.
You will need to maintain some state as to whether the button is "on" or "off". I would do this by creating a closure over a buttonState variable:
const setText = ( text ) => () => {
document.getElementById('toggled').innerHTML = text;
};
const toggleOff = setText('off');
const toggleOn = setText('on');
const makeClickhandler = () => {
let buttonState = false;
return () => {
buttonState ? toggleOff() : toggleOn();
buttonState = !buttonState;
}
};
document.getElementById('yourbuttonid').addEventListener('click', makeClickhandler());
<button id='yourbuttonid'>Toggle</button>
<span id='toggled'>off</span>
I can imagine different ways to achieve it.
The first to come to my mind would be something like:
var button = document.getElementById('toggle');
var state = document.getElementById('current-state');
button.addEventListener("click", toggleState);
function toggleState() {
if ( button.dataset.state == "on" ) {
button.dataset.state = "off";
state.innerHTML = "I'm off";
} else {
button.dataset.state = "on";
state.innerHTML = "I'm on";
}
}
<button id="toggle" data-state="off">Toggle me!</button>
<div id="current-state">I'm off</div>
A similar but slightly more compact approach to Alex Young's:
function toggleOn() {
console.log( 'on' );
}
function toggleOff() {
console.log( 'off' );
}
var button = document.getElementById( 'button' );
button.addEventListener( 'click', function clickToggle() {
clickToggle.state = !clickToggle.state;
clickToggle.state ? toggleOn() : toggleOff();
} );
<button id="button">Toggle</button>
This uses the fact that you can attach properties to named functions this way. I'm not sure what the exact terminology for this is.
To address Joe Frambach's valid concerns, addressed in the comments, you could change it to:
button.addEventListener( 'click', function clickToggle() {
clickToggle.state = !clickToggle.state;
return ( clickToggle.state ? toggleOn : toggleOff ).apply( this, arguments );
} );

Prototype.js how to fix use of clearTimeout( )

I'm using Prototype.js to load an html element when the user performs a mouseover on certain list items. I'm using setTimeout() to load the content only if the mouse is still over the list item after a given amount of time. I want to use clearTimeout when the user performs a mouseout on the same list item.
clearTimeout() is not clearing my timeout. I am pretty sure this is because of a common variable scope issue hidden from me by my lack of familiarity with Prototype.js
Can someone point out the flaw in this code or determine what I need to add to make the clearTimeout() function work properly?
document.observe( 'dom:loaded', function() {
var timeout;
$$('.nav-primary li.category').each( function( item ) {
item.observe('mouseover', function(event) {
event.stopPropagation();
categoryId = event.currentTarget.id;
getCategoryBlurb(categoryId);
timeout = setTimeout( function() {
showCategoryInfo(categoryData, categoryId);
}, waitTime);
});
item.observe('mouseout', function(event) {
event.stopPropagation();
clearTimeout(timeout);
});
});
});
Updated Code
$$('.nav-primary li.category').each( function( item ) {
var timeout = null;
item.observe('mouseover', function(event) {
event.stopPropagation();
categoryId = event.currentTarget.id;
getCategoryBlurb(categoryId);
if( timeout === null ) {
timeout = setTimeout( function() {
showCategoryInfo(categoryData, categoryId);
}, waitTime);
}
console.log(timeout);
});
item.observe('mouseout', function(event) {
if( timeout !== null ) {
console.log(timeout);
clearTimeout(timeout);
timeout = null;
}
});
});
clear the timeout before you set it
if (timeout) { clearTimeout(timeout); }
timeout = setTimeout( function() { /* code here */ });

removeEventListener not working

Adds listener
for ( i = 0; i < kbButtons.length; i++ ) {
kbButtons[i].addEventListener("click", function() { clickKbButton( this ); }, false);
}
Should remove listener
function clickKbButton ( elem ) {
elem.removeEventListener("click", function() { clickKbButton( this ); }, false);
elem.id = "invis"
}
Everything is working fine, no errors in console, button click works but it's not being removed after I click it
As per documentation, my guess is that event handler should reference the same function:
for ( i = 0; i < kbButtons.length; i++ ) {
kbButtons[i].addEventListener("click", clickKbButton, false);
}
function clickKbButton ( ev ) {
this.removeEventListener("click", clickKbButton, false);
this.id = "invis"
}
Simple fiddle example
I guess you should use a variable reference to the function() { clickKbButton(this); }, the two functions in your addEventListener & removeEventListener are actually two different functions.
var handler = function() { clickKbButton(this) };
then use this handler variable when you add & remove listener.

JQuery pause slideshow and resume with setInterval

I'm aware there's plenty of JQuery slideshows out there but I'm coding my own and have come across an obstacle I've not found an answer to specifically.
Background: An automated JQuery Slideshow plugin with pause/resume on hover/out
Problem: How to pause the slideshow on mousenter, and then finish the remaining time period of the setInterval on mouseleave instead of firing the setInterval again.
Solution: I think the only way to do this would be to use a self-invoking method with a delay attached and a stop() to handle the mouse behaviour which would allow the paused animation to resume for its proper remainder rather than firing the method again?
What are your thoughts?
Here's the code:
(function( $ ){
var methods = {
init: function() {
var cycle = window.setInterval(methods.automate, 1000);
$('.slider_control').on('click', 'span', function(){
methods.automate( $(this).attr('slideNumber') );
});
$('.slider_master_container')
.on({
'mouseenter': function() {
clearInterval(cycle);
},
'mouseleave': function() {
cycle = window.setInterval(methods.automate, 1000);
}
});
},
automate: function( el ) {
var $active = $('.slide.active'),
$next = el ? $('.slide[slideNumber=' + el) : $active.nextOrFirst();
$next.css('z-index', 2);
$active.fadeOut(1500, function() {
$active.css('z-index', 1).show().removeClass('active');
$next.css('z-index', 3).addClass('active');
});
}
};
$.fn.smartSlider = function( method ) {
if ( methods[method] ) {
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.smartSlider' );
}
};
})( jQuery );

cannot debug onmouseover event

/* this is our script for monopoly_first_page.html */
var result;
var button;
var image;
var x = 0;
function animation( animatedObject ){
var hereObject = animatedObject;
alert( hereObject );
/*setInterval( animate( animatedObject, x ), 100 );*/
}
function animate( hereObject, x ){
alert( x );
if( x == 0){
hereObject.style.width++;
}
else{
hereObject.style.width--;
}
if( hereObject.style.width <= 225 ){
x = 0;
}
if( hereObject.style.width >= 300 ){
x = 1;
}
}
function disanimation( animatedObject ){
var hereObject = animatedObject;
clearInterval();
}
window.onload = init;
function init(){
result = document.getElementById( "result" );
button = document.getElementById( "button-container" );
document.getElementById( "button-container" ).onmouseclick = animation( button );
document.getElementById( "button-container" ).onmouseout = disanimation( button );
alert( button );
alert( button );
}
hi every one...this is one of my source code and im a beginner...i faced a problem and it is where i wrote this statement:
document.getElementById( "button-container" ).onmouseclick = animation( button );
when function init begins to run function animation also execetues... but im sure im not rolling my mouse over the specified DIV...
what is the problem?
You need to pass a function to any handlers. What is happening with your code is that it calls animation(button) then sets that value to the onmouseclick property. Since the animation(...) function doesn't return a function, nothing beneficial will happen.
This would be a lot closer.
whatever.onmouseclick = animation;
If you need to, you could also do this: (assuming you want a specific button passed)
whatever.onmouseclick = function(e) { animation(button); }
just wanted to add to john, you can also do
document.getElementById( "button-container" ).addEventListener("click",function(){animation(button);},true);
insetead of "onmouseclick"
:-)
As #JohnFisher already mentioned, you assign the RESULT of your function to the event
However I only ever use onclick. Where did you get onmouseclick from?
Also you repeat your getElementById unnecessarily and have an init that is an onload so consolidate it:
window.onload = function() {
var button = document.getElementById( "button-container" );
// button is not necessarily known or the same at the time of the click so use (this)
button.onclick = function() { animation(this); }
button.onmouseout = function() { disanimation(this); }
}

Categories

Resources