UNPKG

outside-click-js

Version:
94 lines (85 loc) 2.87 kB
// 手动添加的umd模式 (function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define([], factory) } else if (typeof module === 'object' && module.exports) { // Node. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like Node. module.exports = factory() } else { // Browser globals (root is window) root.$outsideClick = factory() } }(typeof self !== 'undefined' ? self : this, function () { // 判断是否有windows对象(浏览器环境) const HAS_WINDOWS = typeof window !== 'undefined' // 判断是否有navigator const HAS_NAVIGATOR = typeof navigator !== 'undefined' // 是否支持touch const IS_TOUCH = HAS_WINDOWS && ('ontouchstart' in window || (HAS_NAVIGATOR && navigator.msMaxTouchPoints > 0)) // 默认的触发事件 const EVENTS = IS_TOUCH ? ['touchstart', 'click'] : ['click'] // 默认的拦截器 const MIDDLEWARE = e => e // 缓存事件 const cacheListener = [] // 对外暴露函数 function clickOutside({ el, events, handler, middleware }) { const params = processParams({ el, events, handler, middleware }) params.events.forEach(event => { const instance = { event, el, handler: (e) => clickOutsideHandle(params.el, e, params.handler, params.middleware) } cacheListener.push(instance) onEvent(instance) }) } // 处理参数 function processParams({ el, events, handler, middleware }) { return { el, handler, events: events ? events : EVENTS, middleware: middleware ? middleware : MIDDLEWARE } } // 注册事件 function onEvent({ event, handler }) { return setTimeout(() => document.addEventListener(event, handler), 0) } // 注销事件 function offEvent(event, handler) { return document.removeEventListener(event, handler) } // 核心处理函数 function clickOutsideHandle(el, e, handler, middleware) { // contains 传入的节点是否有调用节点的子节点 // 是否是当前节点的外部节点 const isClickOutside = e.target !== el && !el.contains(e.target) // 内部节点就不做处理 if (!isClickOutside) return // 中间拦截器,同时会执行 if (middleware(e, el)) { handler(e, el) } } // 对外注销函数 function removeClickOutside(targetElement) { // 遍历已绑定的 cacheListener.forEach(({event, el, handler}) => { // 如果没有指定元素,则全部事件注销 if (!targetElement) { return offEvent(event, handler) } // 指定元素,则针对指定去注销 if (targetElement === el) { return offEvent(event, handler) } }) } return { clickOutside, removeClickOutside } }))