Files
mixtape/zero.Web.UI/directives/clickoutside.js
T
2020-10-14 15:47:57 +02:00

103 lines
2.1 KiB
JavaScript

var Helpers = {
isServer(vNode)
{
return false;
//return typeof vNode.componentInstance !== 'undefined' && vNode.componentInstance.$isServer;
},
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;
}
}
return false;
},
validate(binding)
{
if (typeof binding.value !== 'function')
{
console.warn('v-click-outside: provided expression ' + binding.expression + ' is not a function.');
return false;
}
return true;
}
};
/// calls the passed function when a click happens outside the target element
export default {
name: 'click-outside',
beforeMount(el, binding, vNode)
{
if (!Helpers.validate(binding)) return;
// Define Handler and cache it on the element
function handler(e)
{
if (!binding.instance) 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) || Helpers.isPopup(binding.instance.popupItem, elements) || !el.__vueClickOutside__)
{
return;
}
el.__vueClickOutside__.callback(e);
}
// add Event Listeners
el.__vueClickOutside__ = {
handler: handler,
callback: binding.value
};
setTimeout(() =>
{
!Helpers.isServer(vNode) && document.addEventListener('click', handler);
}, 200);
},
updated(el, binding)
{
if (Helpers.validate(binding))
{
el.__vueClickOutside__.callback = binding.value;
}
},
unmounted(el, binding, vNode)
{
!Helpers.isServer(vNode) && document.removeEventListener('click', el.__vueClickOutside__.handler);
delete el.__vueClickOutside__;
}
};