├── .gitattributes ├── LICENSE ├── Makefile ├── README.md ├── jquery.exitintent.js ├── jquery.exitintent.min.js └── test.html /.gitattributes: -------------------------------------------------------------------------------- 1 | *.min.js -diff 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Flávio Veloso 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | JSMIN = closure-compiler 2 | 3 | all: min 4 | 5 | min: jquery.exitintent.min.js 6 | 7 | jquery.exitintent.min.js: jquery.exitintent.js 8 | $(JSMIN) < $? > $@ 9 | 10 | clean: 11 | rm -f *~ 12 | 13 | .PHONY: all min clean 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | jQuery Exit Intent Plugin 2 | ========================= 3 | 4 | The jQuery Exit Intent plugin try to anticipate when the user is about 5 | to leave the current page, and fire an event when it thinks they are 6 | doing so. You can react to this event to display modal dialogues, 7 | change page text, etc., to try to grab user's attention and 8 | (hopefully) made them change their minds. 9 | 10 | 11 | Requirements 12 | ------------ 13 | 14 | 1. jQuery >= 1.4 15 | 16 | 17 | Installation 18 | ------------ 19 | 20 | 1. Download the plugin 21 | 22 | 2. Include the following line *after* jQuery: 23 | 24 | 25 | 26 | NB: adjust the path as necessary 27 | 28 | 3. Enable the plugin in your site: 29 | 30 | $.exitIntent('enable'); 31 | 32 | 4. Listen to the `exitintent` event, and act accordingly: 33 | 34 | $(document).bind('exitintent', 35 | function() { 36 | console.log('Oops... trying to leave the page'); 37 | }); 38 | 39 | 40 | Reference 41 | --------- 42 | 43 | 1. Enable the plugin: 44 | 45 | $.exitIntent('enable') 46 | 47 | 2. Disable the plugin: 48 | 49 | $.exitIntent('disable') 50 | 51 | 3. Use customized settings when enabling: 52 | 53 | $.exitIntent('disable', { 'sensitivity': 100 }) 54 | 55 | 56 | ### Settings 57 | 58 | The second parameter to the `$.exitIntent` plugin call can contain a 59 | settings object. The following settings are recognized: 60 | 61 | - `sensitivity` - adjust the sensitivity to detect when the user is 62 | about to exit. In practical terms, this is the time (in 63 | milliseconds) the user is allowed to "exit" your page, but come back 64 | without triggering the `exitintent`. Default: 300. 65 | 66 | 67 | FAQ 68 | --- 69 | 70 | 1. How do I display a modal popup when the user is trying to leave my 71 | page? 72 | 73 | This plugin only deals with detecting when the user is leaving the 74 | page, and triggering the `exitintent` event. It's up to you do 75 | define *what* you want to do when the user is leaving. For example, 76 | if you want to display a modal dialog, you may use your preferred 77 | jQuery modal plugin to display the modal. 78 | 79 | 2. How do I detect an exit intent on my mobile site? 80 | 81 | There are no interesting events in a mobile site that can be used 82 | to try detect if the user is going to exit. This may be extremely 83 | difficult to implement reliably, if not impossible. 84 | 85 | 86 | Future Improvements 87 | ------------------- 88 | 89 | 1. Detect when users intend to exit by clicking on an external link 90 | 91 | 2. Detect when users intend to exit by closing the browser 92 | window. This can be done by using some heuristics, for example, 93 | when exiting from the bottom of the browser in MS Windows, the 94 | browser is close to the bottom of the screen, and not returning 95 | after some milliseconds. 96 | 97 | Contact me at `flaviovs at magnux dot com` if you'd like to see these 98 | improvements added to the plugin. 99 | 100 | 101 | Legal 102 | ----- 103 | Copyright (C) 2016 Flávio Veloso 104 | 105 | This plugin is released under the terms of the MIT license. See the 106 | LICENSE file for more details. 107 | 108 | If you think you found a bug in this plugin, please visit 109 | https://github.com/flaviovs/jquery.exitintent/issues and open a new 110 | issue. 111 | -------------------------------------------------------------------------------- /jquery.exitintent.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | 'use strict'; 3 | 4 | var timer; 5 | 6 | function trackLeave(ev) { 7 | if (ev.clientY > 0) { 8 | return; 9 | } 10 | 11 | if (timer) { 12 | clearTimeout(timer); 13 | } 14 | 15 | if ($.exitIntent.settings.sensitivity <= 0) { 16 | $.event.trigger('exitintent'); 17 | return; 18 | } 19 | 20 | timer = setTimeout( 21 | function() { 22 | timer = null; 23 | $.event.trigger('exitintent'); 24 | }, $.exitIntent.settings.sensitivity); 25 | } 26 | 27 | function trackEnter() { 28 | if (timer) { 29 | clearTimeout(timer); 30 | timer = null; 31 | } 32 | } 33 | 34 | $.exitIntent = function(enable, options) { 35 | $.exitIntent.settings = $.extend($.exitIntent.settings, options); 36 | 37 | if (enable == 'enable') { 38 | $(window).mouseleave(trackLeave); 39 | $(window).mouseenter(trackEnter); 40 | } else if (enable == 'disable') { 41 | trackEnter(); // Turn off any outstanding timer 42 | $(window).unbind('mouseleave', trackLeave); 43 | $(window).unbind('mouseenter', trackEnter); 44 | } else { 45 | throw "Invalid parameter to jQuery.exitIntent -- should be 'enable'/'disable'"; 46 | } 47 | } 48 | 49 | $.exitIntent.settings = { 50 | 'sensitivity': 300 51 | }; 52 | 53 | })(jQuery); 54 | -------------------------------------------------------------------------------- /jquery.exitintent.min.js: -------------------------------------------------------------------------------- 1 | (function(a){function d(e){0=a.exitIntent.settings.sensitivity?a.event.trigger("exitintent"):b=setTimeout(function(){b=null;a.event.trigger("exitintent")},a.exitIntent.settings.sensitivity))}function c(){b&&(clearTimeout(b),b=null)}var b;a.exitIntent=function(b,f){a.exitIntent.settings=a.extend(a.exitIntent.settings,f);if("enable"==b)a(window).mouseleave(d),a(window).mouseenter(c);else if("disable"==b)c(),a(window).unbind("mouseleave",d),a(window).unbind("mouseenter", 2 | c);else throw"Invalid parameter to jQuery.exitIntent -- should be 'enable'/'disable'";};a.exitIntent.settings={sensitivity:300}})(jQuery); 3 | -------------------------------------------------------------------------------- /test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | jQuery Exit Intent Plugin 5 | 6 | 7 | 19 | 45 | 46 | 47 |
48 |

Please don't leave this page

49 |

For more details, check the jQuery Exit Intent Plugin page.

50 |
51 |
52 |

I said don't leave this page!

53 |

Got it!

54 |
55 |
56 |

Please don't leave this page, even after scrolling here

57 |
58 | 59 | 60 | --------------------------------------------------------------------------------