From cb5d43841aa672af24816dcd8caa1a4c27ed4bef Mon Sep 17 00:00:00 2001 From: Colin O'Dell Date: Wed, 16 Jul 2014 13:54:33 -0400 Subject: [PATCH] Add timed delay which is cancelled by the mouse re-entering. Fixes #48. --- README.md | 11 +++++++++++ source/ouibounce.js | 23 +++++++++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2627e44..dd5f7e6 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ Ouibounce offers a few options, such as: - [Sensitivity](#sensitivity) - [Aggressive mode](#aggressive-mode) - [Timer](#set-a-min-time-before-ouibounce-fires) +- [Delay](#delay) - [Callback](#callback) - [Cookie expiration](#cookie-expiration) - [Cookie domain](#cookie-domain) @@ -101,6 +102,16 @@ _Example:_ ouibounce(document.getElementById('ouibounce-modal'), { timer: 0 }); ``` +##### Delay +By default, Ouibounce will show the modal immediately. You could instead configure it to wait `x` milliseconds before showing the modal. If the user's mouse re-enters the body before `delay` ms have passed, the modal will not appear. This can be used to provide a "grace period" for visitors instead of immediately presenting the modal window. + +_Example:_ + +```js +// Wait 100 ms +ouibounce(document.getElementById('ouibounce-modal'), { delay: 100 }); +``` + ##### Callback You can add a callback, which is a function that will run once Ouibounce has been triggered, by using the `callback` option. diff --git a/source/ouibounce.js b/source/ouibounce.js index e1d062d..3aec647 100644 --- a/source/ouibounce.js +++ b/source/ouibounce.js @@ -3,10 +3,12 @@ function ouibounce(el, config) { aggressive = config.aggressive || false, sensitivity = setDefault(config.sensitivity, 20), timer = setDefault(config.timer, 1000), + delay = setDefault(config.delay, 0), callback = config.callback || function() {}, cookieExpire = setDefaultCookieExpire(config.cookieExpire) || '', cookieDomain = config.cookieDomain ? ';domain=' + config.cookieDomain : '', sitewide = config.sitewide === true ? ';path=/' : '', + _delayTimer = null, _html = document.getElementsByTagName('html')[0]; function setDefault(_property, _default) { @@ -26,13 +28,21 @@ function ouibounce(el, config) { setTimeout(attachOuiBounce, timer); function attachOuiBounce() { _html.addEventListener('mouseleave', handleMouseleave); + _html.addEventListener('mouseenter', handleMouseenter); _html.addEventListener('keydown', handleKeydown); } function handleMouseleave(e) { if (e.clientY > sensitivity || (checkCookieValue('viewedOuibounceModal', 'true') && !aggressive)) return; - fire(); - callback(); + + _delayTimer = setTimeout(_fireAndCallback, delay); + } + + function handleMouseenter(e) { + if (_delayTimer) { + clearTimeout(_delayTimer); + _delayTimer = null; + } } var disableKeydown = false; @@ -41,8 +51,7 @@ function ouibounce(el, config) { else if(!e.metaKey || e.keyCode != 76) return; disableKeydown = true; - fire(); - callback(); + _delayTimer = setTimeout(_fireAndCallback, delay); } function checkCookieValue(cookieName, value) { @@ -60,6 +69,11 @@ function ouibounce(el, config) { return cookies[cookieName] === value; } + function _fireAndCallback() { + fire(); + callback(); + } + function fire() { // You can use ouibounce without passing an element // https://github.com/carlsednaoui/ouibounce/issues/30 @@ -92,6 +106,7 @@ function ouibounce(el, config) { // remove listeners _html.removeEventListener('mouseleave', handleMouseleave); + _html.removeEventListener('mouseenter', handleMouseenter); _html.removeEventListener('keydown', handleKeydown); }