forked from vue-bulma/click-outside
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
73 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,85 @@ | ||
function validate(binding) { | ||
if (typeof binding.value !== 'function') { | ||
console.warn('[Vue-click-outside:] provided expression', binding.expression, 'is not a function.') | ||
return false | ||
if (typeof binding.value !== 'function') { | ||
// eslint-disable-next-line | ||
console.warn('[Vue-click-outside:] provided expression', binding.expression, 'is not a function.') | ||
return false | ||
} | ||
|
||
return true | ||
} | ||
|
||
return true | ||
} | ||
|
||
function isPopup(popupItem, elements) { | ||
if (!popupItem || !elements) | ||
return false | ||
|
||
for (var i = 0, len = elements.length; i < len; i++) { | ||
try { | ||
if (popupItem.contains(elements[i])) { | ||
return true | ||
} | ||
if (elements[i].contains(popupItem)) { | ||
function isPopup(popupItem, elements) { | ||
if (!popupItem || !elements) | ||
return false | ||
for (var i = 0, len = elements.length; i < len; i++) { | ||
try { | ||
if (popupItem.contains(elements[i])) { | ||
return true | ||
} | ||
if (elements[i].contains(popupItem)) { | ||
return false | ||
} | ||
} catch(e) { | ||
return false | ||
} | ||
} catch(e) { | ||
return false | ||
} | ||
|
||
return false | ||
} | ||
|
||
function isServer(vNode) { | ||
return typeof vNode.componentInstance !== 'undefined' && vNode.componentInstance.$isServer | ||
} | ||
|
||
return false | ||
} | ||
|
||
function isServer(vNode) { | ||
return typeof vNode.componentInstance !== 'undefined' && vNode.componentInstance.$isServer | ||
} | ||
|
||
exports = module.exports = { | ||
bind: function (el, binding, vNode) { | ||
if (!validate(binding)) return | ||
|
||
// Define Handler and cache it on the element | ||
function handler(e) { | ||
if (!vNode.context) return | ||
|
||
// some components may have related popup item, on which we shall prevent the click outside event handler. | ||
var elements = e.path || (e.composedPath && e.composedPath()) | ||
elements && elements.length > 0 && elements.unshift(e.target) | ||
|
||
if (el.contains(e.target) || isPopup(vNode.context.popupItem, elements)) return | ||
|
||
el.__vueClickOutside__.callback(e) | ||
// Since IE11 doesn't support e.composedPath() | ||
function composedPath (el) { | ||
var path = [] | ||
while (el) { | ||
path.push(el) | ||
if (el.tagName === 'HTML') { | ||
path.push(document) | ||
path.push(window) | ||
return path | ||
} | ||
el = el.parentNode | ||
} | ||
} | ||
|
||
// add Event Listeners | ||
el.__vueClickOutside__ = { | ||
handler: handler, | ||
callback: binding.value | ||
} | ||
!isServer(vNode) && document.addEventListener('click', handler) | ||
}, | ||
exports = module.exports = { | ||
bind: function (el, binding, vNode) { | ||
if (!validate(binding)) return | ||
|
||
// Define Handler and cache it on the element | ||
function handler(e) { | ||
if (!vNode.context) return | ||
|
||
// some components may have related popup item, on which we shall prevent the click outside event handler. | ||
var elements = e.path || (e.composedPath && e.composedPath()) || composedPath(e.target) | ||
elements && elements.length > 0 && elements.unshift(e.target) | ||
|
||
update: function (el, binding) { | ||
if (validate(binding)) el.__vueClickOutside__.callback = binding.value | ||
}, | ||
if (el.contains(e.target) || isPopup(vNode.context.popupItem, elements)) return | ||
|
||
el.__vueClickOutside__.callback(e) | ||
} | ||
|
||
// add Event Listeners | ||
el.__vueClickOutside__ = { | ||
handler: handler, | ||
callback: binding.value | ||
} | ||
const clickHandler = 'ontouchstart' in document.documentElement ? 'touchstart' : 'click' | ||
!isServer(vNode) && document.addEventListener(clickHandler, handler) | ||
}, | ||
|
||
unbind: function (el, binding, vNode) { | ||
// Remove Event Listeners | ||
!isServer(vNode) && document.removeEventListener('click', el.__vueClickOutside__.handler) | ||
delete el.__vueClickOutside__ | ||
update: function (el, binding) { | ||
if (validate(binding)) el.__vueClickOutside__.callback = binding.value | ||
}, | ||
|
||
unbind: function (el, binding, vNode) { | ||
// Remove Event Listeners | ||
const clickHandler = 'ontouchstart' in document.documentElement ? 'touchstart' : 'click' | ||
!isServer(vNode) && document.removeEventListener(clickHandler, el.__vueClickOutside__.handler) | ||
delete el.__vueClickOutside__ | ||
} | ||
} | ||
} |