I need to initiate the event handler after 3 seconds of being focused on an image. How should I go about it?
Also, I need to trigger another event handler, when I am at a particular part of an image, say the approximate middle of the image. How do I do this?
Use javascript's setTimeout and setInterval functions.
// alert after 2 seconds
setTimeout("alert('Hello World!')", 2000);
// alert every 2 seconds
setInterval("alert('Hello, world!')", 2000);
JavaScript
var timeout;
function message(){
alert('Hey there');
}
function start(){
timeout = setTimeout(message,3000);
}
function stop(){
clearTimeout(timeout);
}
HTML
<img src="HappyCow.jpg" onmouseover="start()" onmouseout="stop()" />
The event handling is rough here (inline >.<), but I think this gets you started.
For question #1: look into timers - you'd start it when the image is in focus (or the mouse hovers over it etc.), then it calls a function after 3 seconds (or any other period). The function would handle what you want to do after three seconds. (Maybe also check if the image is still "active".)
For question #2: One way to do this is Imagemaps, but there may be other/better options.
Hope this helps!
Related
I need to stop my code in a for loop, a sleep() function that stalls time does not work because my HTML does not render in that time and a setTimeout function will continue the loop before doing the set code.
For example, this will display alerts with 1,2,3 before 3 alerts with Stop.
function test(){
for (var i = 1;i<4;i++) {
alert(i);
setTimeout(function(){alert("Stop");},1000);
}
}
How could I wait until continuing with my loop while letting the HTML render ?
Use the DOMContentLoaded event to check once your HTML is fully rendered:
<script>
document.addEventListener('DOMContentLoaded', function(event) {
alert('html loaded');
});
</script>
In your example you could instead just use confirm instead to show a message, and when the user clicks then you use the next setTimeout to show the next message.
But, I think this is not what you are actually looking for.
There are many ways to do asynchronous javascript that doesn't impact html rendering, such as using Web Workers, or pass functions inside of setTimeout and those can use closures to help track where you are, but, have the next setTimeout be called after some processing, and after some event, as these will allow the rendering to continue until certain events or time happens.
scenario:
An animation can be called multiple times.
The animation is called by another event such as a click event.
The animation should not fire until it is sure that all other animation events involving this structure are complete.
example: http://jsfiddle.net/xo6ngbfz/
jQuery( document ).ready(function() {
console.log('run');
jQuery("#animation-object").bind("fire-hide", function () {
jQuery(this).toggle();
});
jQuery('#element').on('click', function () {
console.log('click');
jQuery('*').trigger("fire-hide");
});
});
Further understanding:
This is a very simple animation; but say for instance someone had a set of tiles. These tiles slide up and down on the screen after a link has been clicked on.
If we do not wait for all animations to be complete, the slide effect could stop half way through the animation and revert to whatever animation was last clicked.
I did an example with your code. I hope it could be useful for you!
The key was use a counter for total animations you have and pass a function as a callback for each one:
jQuery(this).toggle("slow", animationFinished);
You shoud do it for each jquery function you want to it notify you that it was finished.
(when function not accept callback, it is enough call animationFinished() after it, see line 14 of the example).
When the counter of animations has finished is equal to the total animation counter, then a function is called and the counter is reseted.
It is no the best way to do it, because each time you add an animation, you have to modify the totalAnimations counter, but at least is an option for now.
Yes, I know this question has been asked before, but I can't find an answer that works. This is an accepted answer from one of the other questions:
$('#element').hover(function()
{
$(this).data('timeout', window.setTimeout(function()
{
alert('hovered for 2 seconds');
}, 2000));
},
function()
{
clearTimeout($(this).data('timeout'));
alert('mouse left');
});
http://jsfiddle.net/nCcxt/
As you see it doesn't do what it's supposed to.
What I need is simple in theory but I can't get it to work - when a user hovers over a link for 2 seconds, a function is called. If the user moves the mouse away before 2 seconds pass, nothing happens.
The code works perfectly fine. It only breaks due to the alert() calls which causes the mouseout event to be triggered.
What do we learn from it? Do not use alert() in combination with focus/hover/mousemove-related events.
By the way, there are already jQuery plugins available for what you want to do: http://cherne.net/brian/resources/jquery.hoverIntent.html
I have a problem involving setinterval. It's probably best to show an example so here's a link here:
http://boudaki.com/testing/carouselTest
Basically I'm having problems making this work like I need it to. When the page loads the content rotates every three seconds and the numbered buttons on the right do so also. when you click on a button the buttons extend and the animation is stopped - all good. Then when you click the little close button at the bottom of the buttons the animation resumes - all good....but then when you come to click on the numbered buttons again the animation keeps on going. Why?
There's rather a lot of code but the setIntervals and clear intervals are:
line 69: on document.ready start the animation off -assign timerId to a global var
line 87: When the user clicks on the numbered button clearinterval in that animation
line 102: when the user clicks on the close button start the animation again
That's it....I just don't get why it doesn't stop the animation the second time around??? Can anyone see why?
Any ideas?
This is a guess, but try bringing all your functions and variables into the $(document).ready(function() {...}) call.
Then change your setInterval() so that you're passing in a reference to the function instead of a string for eval:
timerId = setInterval( rotateForward, 3000 );
Be sure to change all of them.
To be honest I don't know why this would work, but making the variable local may help to ensure that we're dealing with only one version of timerId.
$closeButton.click(function() { ... }); is inside of your loop. That handler is getting added 4 times, so when you click close, 4 timers are added and only 1 is cleared when you open the menu again.
I think the problem is the scoping of timerId. Try changing alert('should stop now'); to alert('should stop now' + timerId);
I'll bet you'll find that timerId is always the same value.
The only thing I can think of is... I'm pretty sure you can't put the () inside the setInterval call. It does seem to work at first, but maybe that's part of the issue? Hard to say... but I'd at least start there.
setInterval("rotateForward", 3000);
Also, maybe try calling the clearInterval every time before you start it.
I have a table with some columns. In each of them is a picture where I have an onmouseover/onmouseout event on it, which shows a message in a div and hides the message.
My problem is, after a user moves quickly from left to right over a lot of images, all mouseover and mouseout events of the images are executed, which looks stupid...
Is it possible to rearrange the internal event stack to avoid this, such that the user executes only the current event (mostly the first one) and then the last one, if it is not the same type?
For example, if mouseover over first image is executed and the mouse moving position stops over an image three times next to the first one. I can avoid all other events firing, because the mouse stopped over an image and the mouseover is like the one where I stopped with the mouse.
How can I avoid this multiple event firing?
You need to check out the hoverIntent plugin, which addresses this problem.
We've had the exact same problem, What we've done is on the mouseover event is to set a variable _mouseOn to true (set to false on mouseout) then set a oneTime event over that fires in say 500 ms.. The one time event will check if the _mouseOn is true and display the image
function Hover() {
_mouseOn = true;
$(document).oneTime(500, "500ms", functionToCheckTheMouseOnAndDisplayTheImage);
};
//Global timeout handle for mouseover and mouseout
var timeoutHandle;
$(document).ready(function() {
BindMouseHover($(".helptext"));
});//closing ready
//bind mouseover and mouseout actions on all elements
function BindMouseHover(elements) {
$(elements).hover(
function() {
timeoutHandle = setTimeout('HandleMouseHover(true)', 1000);
},
function() {
HandleMouseHover(false);
}
);
}
//Handle Mouseover and mouseout events
function HandleMouseHover(bDelay) {
if (bDelay) {
$(".tooltip").show();
}
else {
$(".tooltip").hide();
clearTimeout(timeoutHandle);
}
}
Explanation:
On every mouseover schedule a call to DelayedTooltip(***true*)** after 1000ms and save the setTimeout handle to timeoutHandle
If mouseout happens within that 1000ms interval then simply call clearTimeout(***timeoutHandle*)** to cancel the setTimeout
This can be easily extended to apply to many heterogeneous elements and wire the customize tooltip text based on the element hovered.
Click here to know more about JavaScript Timing Events.
You can't, and shouldn't try to, avoid the events firing. What you should avoid is your code immediately responding to them by doing something that winds up looking stupid. For example, you can have your mouseovers register, with some controller object, which image the user is currently over, and set a short timeout to the function that triggers the actual behavior (removing a previous timeout if it's already running). The mouseout unregisters the image and removes the timeout. That way, when the behavior runs, you only operate on the image that the user moused over most recently.
I think it's better (from http://bavotasan.com/demos/fadehover/, THANKS)
<script>
$(document).ready(function(){
$(".a").hover(
function() {
$(this).stop().animate({"opacity": "0"}, "slow");
},
function() {
$(this).stop().animate({"opacity": "1"}, "slow");
});
});
</script>