├── README.md ├── base.js ├── base.min.js ├── index.js └── package.json /README.md: -------------------------------------------------------------------------------- 1 | # Hover Intent - Vue 2 | 3 | > A vue directive that allows you to trigger a hover event intelligently. Wraps itself around hoverintent.js from https://github.com/tristen/hoverintent 4 | ## Build Setup 5 | ``` bash 6 | # install dependencies 7 | npm install 8 | ``` 9 | To use 10 | ``` 11 | import Vue from 'vue' 12 | import HoverIntent from 'hover-intent-vue'; 13 | Vue.directive('hover-intent', HoverIntent) 14 | ``` 15 | In your component, use it as follows: 16 | ``` 17 | 18 | ``` 19 | Your someMethod callback will receive one single value. True when the hover is triggered, and false when it leaves. 20 | The value must also be passed, as it's a means of fixing an issue with hoverintent not correctly handling manual changes 21 | to the state of the hover. 22 | 23 | When invoking the hoverintent directive, there is an optional 4th parameter (object) which will allow you to change options of hoverintent. Please see base.js for an example of what options ae configurable. 24 | 25 | -------------------------------------------------------------------------------- /base.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | export default function(el, onOver, onOut, options) { 3 | var x, y, pX, pY, 4 | h = {}, 5 | state = 0, 6 | timer = 0, 7 | options = {...{ 8 | sensitivity: 10, 9 | interval: 100, 10 | timeout: 0, 11 | handleFocus: false 12 | }, ...options}, 13 | focused = false, 14 | mouseOver = false; 15 | function delay(el, e) { 16 | if (timer) timer = clearTimeout(timer); 17 | state = 0; 18 | return focused ? undefined : onOut.call(el, e); 19 | } 20 | function tracker(e) { 21 | x = e.clientX; 22 | y = e.clientY; 23 | } 24 | function compare(el, e) { 25 | if (timer) timer = clearTimeout(timer); 26 | if ((Math.abs(pX - x) + Math.abs(pY - y)) < options.sensitivity) { 27 | state = 1; 28 | return focused ? undefined : onOver.call(el, e); 29 | } else { 30 | pX = x; 31 | pY = y; 32 | timer = setTimeout(function() { 33 | compare(el, e); 34 | }, options.interval); 35 | } 36 | } 37 | h.options = function(opt) { 38 | var focusOptionChanged = opt.handleFocus !== options.handleFocus; 39 | options = Object.assign({}, options, opt); 40 | if (focusOptionChanged) { 41 | options.handleFocus ? addFocus() : removeFocus(); 42 | } 43 | return h; 44 | }; 45 | function dispatchOver(e) { 46 | mouseOver = true; 47 | if (timer) timer = clearTimeout(timer); 48 | el.removeEventListener('mousemove', tracker, false); 49 | if (state !== 1) { 50 | pX = e.clientX; 51 | pY = e.clientY; 52 | el.addEventListener('mousemove', tracker, false); 53 | timer = setTimeout(function() { 54 | compare(el, e); 55 | }, options.interval); 56 | } 57 | return this; 58 | } 59 | function dispatchOut(e) { 60 | mouseOver = false; 61 | if (timer) timer = clearTimeout(timer); 62 | el.removeEventListener('mousemove', tracker, false); 63 | if (state === 1) { 64 | timer = setTimeout(function() { 65 | delay(el, e); 66 | }, options.timeout); 67 | } 68 | return this; 69 | } 70 | function dispatchFocus(e) { 71 | if (!mouseOver) { 72 | focused = true; 73 | onOver.call(el, e); 74 | } 75 | } 76 | function dispatchBlur(e) { 77 | if (!mouseOver && focused) { 78 | focused = false; 79 | onOut.call(el, e); 80 | } 81 | } 82 | function addFocus() { 83 | el.addEventListener('focus', dispatchFocus, false); 84 | el.addEventListener('blur', dispatchBlur, false); 85 | } 86 | function removeFocus() { 87 | el.removeEventListener('focus', dispatchFocus, false); 88 | el.removeEventListener('blur', dispatchBlur, false); 89 | } 90 | h.remove = function() { 91 | if (!el) return; 92 | el.removeEventListener('mouseover', dispatchOver, false); 93 | el.removeEventListener('mouseout', dispatchOut, false); 94 | removeFocus(); 95 | }; 96 | h.manualReset = function(){ 97 | state = 1; 98 | dispatchOut(); 99 | } 100 | if (el) { 101 | el.addEventListener('mouseover', dispatchOver, false); 102 | el.addEventListener('mouseout', dispatchOut, false); 103 | } 104 | return h; 105 | }; -------------------------------------------------------------------------------- /base.min.js: -------------------------------------------------------------------------------- 1 | "use strict";export default function(e,t,n,i){var o,u,r,s,c={},v=0,a=0,l=(i={...{sensitivity:10,interval:100,timeout:0,handleFocus:!1},...i},!1),m=!1;function f(e){o=e.clientX,u=e.clientY}function d(n){return m=!0,a&&(a=clearTimeout(a)),e.removeEventListener("mousemove",f,!1),1!==v&&(r=n.clientX,s=n.clientY,e.addEventListener("mousemove",f,!1),a=setTimeout(function(){!function e(n,c){if(a&&(a=clearTimeout(a)),Math.abs(r-o)+Math.abs(s-u) binding.value.change(true), () => binding.value.change(false), binding.value.options ) 10 | }, 11 | unbind(el) { 12 | el.hoverintent.remove() 13 | } 14 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hover-intent-vue", 3 | "version": "1.0.0", 4 | "description": "A vue directive ", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/hybridwebdev/hover-intent-vue.git" 12 | }, 13 | "keywords": [ 14 | "vue", 15 | "hover-intent", 16 | "hover" 17 | ], 18 | "author": "Justin Lindsay", 19 | "license": "MIT", 20 | "bugs": { 21 | "url": "https://github.com/hybridwebdev/hover-intent-vue/issues" 22 | }, 23 | "homepage": "https://github.com/hybridwebdev/hover-intent-vue#readme" 24 | } 25 | --------------------------------------------------------------------------------