12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- import Vue from "vue";
- import { on } from "./dom";
- const nodeList = [];
- const ctx = "@@clickoutsideContext";
- let startClick;
- let seed = 0;
- !Vue.prototype.$isServer && on(document, "mousedown", e => (startClick = e));
- !Vue.prototype.$isServer &&
- on(document, "mouseup", e => {
- nodeList.forEach(node => node[ctx].documentHandler(e, startClick));
- });
- function createDocumentHandler(el, binding, vnode) {
- return function(mouseup = {}, mousedown = {}) {
- if (
- !vnode ||
- !vnode.context ||
- !mouseup.target ||
- !mousedown.target ||
- el.contains(mouseup.target) ||
- el.contains(mousedown.target) ||
- el === mouseup.target ||
- (vnode.context.popperElm &&
- (vnode.context.popperElm.contains(mouseup.target) ||
- vnode.context.popperElm.contains(mousedown.target)))
- )
- return;
- if (
- binding.expression &&
- el[ctx].methodName &&
- vnode.context[el[ctx].methodName]
- ) {
- vnode.context[el[ctx].methodName]();
- } else {
- el[ctx].bindingFn && el[ctx].bindingFn();
- }
- };
- }
- /**
- * v-clickoutside
- * @desc 点击元素外面才会触发的事件
- * @example
- * ```vue
- * <div v-element-clickoutside="handleClose">
- * ```
- */
- export default {
- bind(el, binding, vnode) {
- nodeList.push(el);
- const id = seed++;
- el[ctx] = {
- id,
- documentHandler: createDocumentHandler(el, binding, vnode),
- methodName: binding.expression,
- bindingFn: binding.value
- };
- },
- update(el, binding, vnode) {
- el[ctx].documentHandler = createDocumentHandler(el, binding, vnode);
- el[ctx].methodName = binding.expression;
- el[ctx].bindingFn = binding.value;
- },
- unbind(el) {
- let len = nodeList.length;
- for (let i = 0; i < len; i++) {
- if (nodeList[i][ctx].id === el[ctx].id) {
- nodeList.splice(i, 1);
- break;
- }
- }
- delete el[ctx];
- }
- };
|