wp-element-ui
Version:
element-ui二开版
159 lines (153 loc) • 6.18 kB
JavaScript
import {on, off} from 'element-ui/src/utils/dom';
import {isObject} from 'element-ui/src/utils/types';
import Vue from 'vue';
/** 给绑定元素注册mouseenter事件 */
function registEvent(el, binding, vnode) {
const {arg, value} = binding;
const _this = vnode.context;
let popper = _this.$refs[arg];
if (!popper) return;
const componentOptions = popper ? popper.$vnode.componentOptions : null;
const isPopConfirm = componentOptions ? componentOptions.tag === 'el-popconfirm' : false;
if (isPopConfirm) {
const title = value || (el.dataset ? el.dataset.popconfirmTitle : '');
if (!componentOptions.propsData.title) {
popper.setTitle(title);
}
popper = popper.$children[0];
} else {
if (!componentOptions.propsData.title) {
const popoverTitle = el.dataset ? el.dataset.popoverTitle : '';
const title = isObject(value) ? (value.title || popoverTitle) : popoverTitle;
popper.setTitle(title);
}
if (!componentOptions.propsData.content) {
const popoverContent = el.dataset ? el.dataset.popoverContent : '';
const content = isObject(value) ? (value.content || popoverContent) : value || popoverContent;
popper.setContent(content);
}
}
const reference = el;
// 这点当存在多个referenceElm指向同一个popover时,点击其中一个如果popover是显示状态的话,会出现闪现的问题
let flag = true;
if (popper.showPopper && popper.referenceElm !== el) {
flag = false;
}
_this.$nextTick(() => {
// 修改参照属性为当前悬浮元素
popper.referenceElm = reference;
// 同时设置实例对象中的私有参照属性
// (不得不改私有属性,不改就没法重新计算,popperJS 目录 'element-ui/src/utils/popper.js')
popper.popperJS && (popper.popperJS._reference = reference);
// 根据新参照重新计算位置
popper.updatePopper();
// 触发el-popover组件内部的handleMouseEnter事件
if (el.__ElPopoverTrigger__ === 'hover') {
popper.handleMouseEnter();
el.__ElPopoverHandleKeydown__ = popper.handleKeydown;
on(reference, 'keydown', el.__ElPopoverHandleKeydown__);
on(popper.$refs.popper, 'mouseenter', popper.handleMouseEnter);
on(popper.$refs.popper, 'mouseleave', popper.handleMouseLeave);
_this.$once('hook:beforeDestroy', () => {
off(popper.$refs.popper, 'mouseenter', popper.handleMouseEnter);
off(popper.$refs.popper, 'mouseleave', popper.handleMouseLeave);
});
} else if (el.__ElPopoverTrigger__ === 'click') {
popper.handleClick();
if (flag) {
popper.doToggle();
}
el.__ElPopoverHandleDocumentClick__ = popper.handleDocumentClick;
el.__ElPopoverHandleKeydown__ = popper.handleKeydown;
on(document, 'click', el.__ElPopoverHandleDocumentClick__);
on(reference, 'keydown', el.__ElPopoverHandleKeydown__);
} else if (el.__ElPopoverTrigger__ === 'focus') {
popper.doShow();
el.__ElPopoverHandleKeydown__ = popper.handleKeydown;
on(reference, 'keydown', el.__ElPopoverHandleKeydown__);
}
});
}
/** 给绑定元素注册mouseleave事件 */
function registLeaveEvent(el, binding, vnode) {
const {arg} = binding;
const _this = vnode.context;
let popper = _this.$refs[arg];
const componentOptions = popper ? popper.$vnode.componentOptions : null;
const isPopConfirm = componentOptions ? componentOptions.tag === 'el-popconfirm' : false;
if (isPopConfirm) {
popper = popper.$children[0];
}
if (el.__ElPopoverTrigger__ === 'hover') {
popper.handleMouseLeave();
} else if (el.__ElPopoverTrigger__ === 'focus') {
popper.doClose();
}
}
function bindEvent(el) {
if (el.__ElPopoverTrigger__ === 'hover') {
on(el, 'mouseenter', el.__ElPopoverMulEnterEvent__);
on(el, 'mouseleave', el.__ElPopoverMulLeaveEvent__);
} else if (el.__ElPopoverTrigger__ === 'click') {
on(el, 'click', el.__ElPopoverMulEnterEvent__);
} else if (el.__ElPopoverTrigger__ === 'focus') {
if (el.querySelector('input, textarea')) {
on(el, 'focusin', el.__ElPopoverMulEnterEvent__);
on(el, 'focusout', el.__ElPopoverMulLeaveEvent__);
} else {
on(el, 'mousedown', el.__ElPopoverMulEnterEvent__);
on(el, 'mouseup', el.__ElPopoverMulLeaveEvent__);
}
} else if (el.__ElPopoverTrigger__ === 'manual') {
el.__ElPopoverMulEnterEvent__(el);
}
}
function offEvent(el) {
if (el.__ElPopoverTrigger__ === 'hover') {
off(el, 'mouseenter', el.__ElPopoverMulEnterEvent__);
off(el, 'mouseleave', el.__ElPopoverMulLeaveEvent__);
off(el, 'keydown', el.__ElPopoverHandleKeydown__);
} else if (el.__ElPopoverTrigger__ === 'click') {
off(el, 'click', el.__ElPopoverMulEnterEvent__);
off(el, 'keydown', el.__ElPopoverHandleKeydown__);
off(document, 'click', el.__ElPopoverHandleDocumentClick__);
} else if (el.__ElPopoverTrigger__ === 'focus') {
off(el, 'keydown', el.__ElPopoverHandleKeydown__);
if (el.querySelector('input, textarea')) {
off(el, 'focusin', el.__ElPopoverMulEnterEvent__);
off(el, 'focusout', el.__ElPopoverMulLeaveEvent__);
} else {
off(el, 'mousedown', el.__ElPopoverMulEnterEvent__);
off(el, 'mouseup', el.__ElPopoverMulLeaveEvent__);
}
}
}
function init(el, binding, vnode) {
const popper = vnode.context.$refs[binding.arg];
if (!popper) return;
const componentOptions = popper.$vnode.componentOptions;
const isPopConfirm = componentOptions ? componentOptions.tag === 'el-popconfirm' : false;
if (componentOptions) {
el.__ElPopoverTrigger__ = isPopConfirm ? 'click' : componentOptions.propsData.trigger || 'click';
}
bindEvent(el);
}
export default {
bind(el, binding, vnode) {
if (Vue.prototype.$isServer) return;
// 给el添加方法,方便销毁事件
el.__ElPopoverMulEnterEvent__ = (e) => {
registEvent(el, binding, vnode);
};
el.__ElPopoverMulLeaveEvent__ = (e) => {
registLeaveEvent(el, binding, vnode);
};
init(el, binding, vnode);
},
inserted(el, binding, vnode) {
init(el, binding, vnode);
},
unbind(el) {
offEvent(el);
}
};