Writing a Mousestop Event Plugin Using jQuery

Share this article

I recently published a jQuery tooltip plugin of my own that was pretty simple, it basically popped up when you hovered over an element, nothing fancy. However I noticed the default browser had a bit of a delay before it actually shows up. It also won’t show up until you stop moving your mouse around on the element. Lastly there was only a certain amount of time you had to stop moving your mouse before the tooltip didn’t appear at all. I wanted to rebuild this functionality and ended up writing my own little mousestop event plugin in jQuery which I thought I would share. It’s a pretty simple little piece of code that basically triggers when a mouse stops over a certain element with a few options for the timers. You can check out documentation on it here: jQuery mousestop plugin Also check it out in action with my tooltip plugin here: jQuery tooltip plugin

1. The mouse stop event

First we just want to know how to detect a mouse stop, this is actually pretty easy and only requires a single timer to constantly loop until enough delay has occurred.
var movementTimer = null;

    $("#element").mousemove(function(e)
    {
    	clearTimeout(movementTimer);
    	movementTimer = setTimeout(function()
    	{
    		//do something here
    	}, 300);
    })

2. Stopping the Timer on Mouseout

We have our mousestop working, but now what happens when we mouseout of the element? We wouldn’t want mousestop event to trigger, since we are technically not stopping on the element. All we need to do here is add a mouseout event that clears our timer to make sure it doesn’t get executed.
var movementTimer = null;

    $("#element").mouseout(function(e)
    {
    	clearTimeout(movementTimer);
    })

3. Setting the Grace Period

Here is where it starts getting tricker. If we want to set an amount of time that the mousestop event has to trigger before it’s completely turned off, we will need to introduce a second timer.
var counter = 0;
    var counterMax = 20;
    var movement = false;

    elem
    .mouseover(function(e)
    {
    	movement = true;
    	
    	//check if movement has stopped to a maximum time of 100*counterMax, after that event will not run at all unless you re-mouseover
    	displayTimer = setInterval(function()
    	{
    		counter++;
    		
    		if(counter < counterMax)
    		{
    			if(!movement)
    			{
    				//run some code
    			}
    			//else do nothing, just iterate
    		}
    	}, 100)
    })
This starts a timer that checks to see if movement has stopped, which would be set by our previous timer. The max here is 20 intervals for 100 milliseconds each giving us a two second grace period. Since this timer now controls our function, if it does not execute within the grace period, we are done.

4. Getting Proper Coordinates There is one more crucial piece here that we need to add. Since we are running this from the mouseover event, our event.pageX and event.pageY coordinates will be from where they entered the element, however we will probably want the mouse position of where it is now while the mouse is moving around.
var x = null;
    var y = null;

    var movementTimer = null;

    $("#element").mousemove(function(e)
    {
    	x = e.pageX;
    	y = e.pageY;
    })

5. Putting It All Together

We can now put this all together into a plugin like below. This little jQuery plugin has less than 100 lines of code, and is less than 1KB in size when minified.
(function($)
    {
    	var defaultSettings =
    	{
    		timeToStop		: null,			// the amount of time the stop even thas to run before it will not run at all anymore
    		delayToStop		: '300', 		// the delay for what is considered a "stop"
    		onMouseout		: null,			// function to run when we mouseout of our element
    		onStopMove		: null			// function to run when we start moving again after the stop
    	};
    	
    	$.fn.mousestop = function(func, settings)
    	{
    		settings = $.extend({}, defaultSettings, settings || {});
    		
    		return this.each(function()
    		{
    			var elem = $(this);

    			var movement = false;
    			
    			var displayTimer = null
    			var movementTimer = null;
    		
    			//only need this piece if there is a time limit on when the mouse stop can occur.
    			if(settings.timeToStop != null)
    			{
    				var x = null;
    				var y = null;
    		
    				var counter = 0;
    				var counterMax = Math.ceil(settings.timeToStop / 100);
    				
    				elem
    				.mouseover(function(e)
    				{
    					movement = true;
    					
    					//check if movement has stopped to a maximum time of 100*counterMax, after that event will not run at all unless you re-mouseover
    					displayTimer = setInterval(function()
    					{
    						counter++;
    						
    						if(counter < counterMax)
    						{
    							if(!movement)
    							{
    								clearTimeout(displayTimer);//clear the timeout to avoid any funkiness
    								
    								//set the coordinates for the event to the ones from the document event
    								e.pageX = x;
    								e.pageY = y;
    								
    								func(e);
    							}
    							//else do nothing, just iterate
    						}else movement = false;//we can turn this off to avoid using the timeout in the mousemove
    					}, 100)
    				})
    			}
    			
    			elem
    			.mouseout(function(e)
    			{
    				//kill this timers incase it's still running
    				clearTimeout(displayTimer);
    				clearTimeout(movementTimer);
    				
    				counter = 0;//reset counter for when we mouseover again
    				movement = false;//set movement back to false
    				
    				settings.onMouseout(e);//call our mouseout
    			})
    			.mousemove(function(e)
    			{
    				x = e.pageX;
    				y = e.pageY;
    				
    				if(movement)//if we have moused over this will be on
    				{
    					//clear timer and set again, this will determine our "stop" which will occur if mouse is in same position for the delayToStop time or more milliseconds
    					clearTimeout(movementTimer);
    					movementTimer = setTimeout(function()
    					{
    						movement = false;
    						if(settings.timeToStop == null) func(e);
    					}, settings.delayToStop);
    				}
    				else
    				{
    					settings.onStopMove(e);//call our mousemove - this is after the stop
    					movement = true;
    				}
    			});
    		});
    	}
    })(jQuery);
We really end up providing three types of functionality for our plugin that we can use now. The first is the mousestop that triggers anytime we stop the mouse for a given period of time. The second functionality lets us set the mousestop event only once, which we can do by just setting the timeout really high. The third is the grace period for the mousestop event to be able to trigger at all. This plugin really didn’t take that long to develop especially using jQuery, it really was just a matter of setting some flags on off in the correct order for the timers to function properly. All in all a nice little plugin that gives us an extra event to play with in our code.

About the Author websanova Robert Nova is a web developer with a particular interest in jQuery plugins and finding ways to help developers build their projects as quickly as possible. He is founder of www.websanova.com, a site dedicated to jQuery plugins and other entrepreneurial resources.

Frequently Asked Questions about Writing a MouseStop Event Plugin in jQuery

What is a MouseStop event in jQuery?

A MouseStop event in jQuery is a custom event that is triggered when the mouse pointer stops moving. It’s not a built-in jQuery event, but rather a custom one that you can create using the jQuery special events API. This event can be useful in various scenarios, such as when you want to perform an action only when the user stops moving the mouse, not while it’s in motion.

How can I create a MouseStop event in jQuery?

To create a MouseStop event in jQuery, you need to use the jQuery special events API. This API allows you to define custom events with their own behavior. You can use the ‘setup’, ‘teardown’, ‘add’, and ‘remove’ methods to define how your event should behave. For a MouseStop event, you would typically use the ‘mousemove’ event to start a timer, and if the timer completes without any further ‘mousemove’ events, you trigger the ‘mousestop’ event.

How can I use the MouseStop event in my code?

Once you’ve defined a MouseStop event, you can use it just like any other event in jQuery. You can bind it to an element using the .on() method, and provide a function that will be executed when the event is triggered. For example, you could use $(‘#myElement’).on(‘mousestop’, function() { /* do something */ }); to execute some code whenever the mouse stops moving over the element with the ID ‘myElement’.

What is the difference between MouseStop and MouseOut events?

The MouseStop and MouseOut events in jQuery serve different purposes. The MouseOut event is triggered when the mouse pointer leaves the boundaries of an element, while the MouseStop event is triggered when the mouse pointer stops moving, regardless of its position. Therefore, you would use the MouseOut event to detect when the mouse leaves an element, and the MouseStop event to detect when the mouse stops moving.

Can I use the MouseStop event with other events?

Yes, you can use the MouseStop event in combination with other events. For example, you could use it with the ‘mousemove’ event to perform an action when the mouse stops moving after a certain period of time. You could also use it with the ‘click’ event to perform an action when the user stops moving the mouse and then clicks.

How can I adjust the delay for the MouseStop event?

The delay for the MouseStop event is determined by the timer you set up when defining the event. You can adjust this delay by changing the duration of the timer. For example, if you want the MouseStop event to be triggered after the mouse has been stationary for 2 seconds, you would set the timer to 2000 milliseconds.

Can I use the MouseStop event in all browsers?

The MouseStop event, as a custom jQuery event, should work in all browsers that support jQuery. However, as with any JavaScript code, it’s always a good idea to test your code in multiple browsers to ensure compatibility.

Can I trigger the MouseStop event manually?

Yes, you can trigger the MouseStop event manually using the .trigger() method in jQuery. This can be useful in certain scenarios, such as for testing or when you want to simulate the event for some reason.

Can I unbind the MouseStop event?

Yes, you can unbind the MouseStop event from an element using the .off() method in jQuery. This will prevent the event from being triggered on that element in the future.

Can I use the MouseStop event with touch devices?

The MouseStop event is based on mouse events, which are not always applicable to touch devices. However, you could potentially adapt the concept for touch events, using the ‘touchmove’ event instead of ‘mousemove’. Keep in mind that touch behavior can vary significantly between different devices and browsers, so thorough testing is essential.

Sam DeeringSam Deering
View Author

Sam Deering has 15+ years of programming and website development experience. He was a website consultant at Console, ABC News, Flight Centre, Sapient Nitro, and the QLD Government and runs a tech blog with over 1 million views per month. Currently, Sam is the Founder of Crypto News, Australia.

jQuery
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week
Loading form