使用vue指令怎么实现气泡提示效果-创新互联
使用vue 指令怎么实现气泡提示效果?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

气泡指令
import { on , off , once, contains, elemOffset, position, addClass, removeClass } from '../utils/dom';
import Vue from 'vue'
const global = window;
const doc = global.document;
const top = 15;
export default {
name : 'jc-tips' ,
bind (el , binding , vnode) {
// 确定el 已经在页面里 为了获取el 位置信信
Vue.nextTick(() => {
const { context } = vnode;
const { expression } = binding;
// 气泡元素根结点
const fWarpElm = doc.createElement('div');
// handleFn 气泡里的子元素(自定义)
const handleFn = binding.expression && context[expression] || (() => '');
const createElm = handleFn();
fWarpElm.className = 'hide jc-tips-warp';
fWarpElm.appendChild(createElm);
doc.body.appendChild(fWarpElm);
// 给el 绑定元素待其他操作用
el._tipElm = fWarpElm;
el._createElm = createElm;
// 鼠标放上去的 回调函数
el._tip_hover_fn = function(e) {
// 删除节点函数
removeClass(fWarpElm, 'hide');
fWarpElm.style.opacity = 0;
// 不加延迟 fWarpElm的大小信息 (元素大小是 0 0)---> 删除 class 不是立即渲染
setTimeout(() => {
const offset = elemOffset(fWarpElm);
const location = position(el);
fWarpElm.style.cssText = `left: ${location.left - offset.width / 2}px; top: ${location.top - top - offset.height}px;`;
fWarpElm.style.opacity = 1;
}, 16);
};
//鼠标离开 元素 隐藏 气泡
const handleLeave = function (e) {
fWarpElm.style.opacity = 0;
// transitionEnd 不太好应该加入兼容
once({
el,
type: 'transitionEnd',
fn: function() {
console.log('hide');
addClass(fWarpElm, 'hide');
}
})
};
el._tip_leave_fn = handleLeave;
// 解决 slider 移动结束 提示不消失
el._tip_mouse_up_fn = function (e) {
const target = e.target;
console.log(target);
if (!contains(fWarpElm, target) && el !== target) {
handleLeave(e)
}
};
on({
el,
type: 'mouseenter',
fn: el._tip_hover_fn
});
on({
el,
type: 'mouseleave',
fn: el._tip_leave_fn
});
on({
el: doc.body,
type: 'mouseup',
fn: el._tip_mouse_up_fn
})
});
} ,
// 气泡的数据变化 依赖于 context[expression] 返回的值
componentUpdated(el , binding , vnode) {
const { context } = vnode;
const { expression } = binding;
const handleFn = expression && context[expression] || (() => '');
Vue.nextTick( () => {
const createNode = handleFn();
const fWarpElm = el._tipElm;
if (fWarpElm) {
fWarpElm.replaceChild(createNode, el._createElm);
el._createElm = createNode;
const offset = elemOffset(fWarpElm);
const location = position(el);
fWarpElm.style.cssText = `left: ${location.left - offset.width / 2}px; top: ${location.top - top - offset.height}px;`;
}
})
},
// 删除 事件
unbind (el , bind , vnode) {
off({
el: dov.body,
type: 'mouseup',
fn: el._tip_mouse_up_fn
});
el = null;
}
}slider 组件
../utils/dom const global = window; export const on = ({el, type, fn}) => { if (typeof global) { if (global.addEventListener) { el.addEventListener(type, fn, false) } else { el.attachEvent(`on${type}`, fn) } } }; export const off = ({el, type, fn}) => { if (typeof global) { if (global.removeEventListener) { el.removeEventListener(type, fn) } else { el.detachEvent(`on${type}`, fn) } } }; export const once = ({el, type, fn}) => { const hyFn = (event) => { try { fn(event) } finally { off({el, type, fn: hyFn}) } } on({el, type, fn: hyFn}) }; // 最后一个 export const fbTwice = ({fn, time = 300}) => { let [cTime, k] = [null, null] // 获取当前时间 const getTime = () => new Date().getTime() // 混合函数 const hyFn = () => { const ags = argments return () => { clearTimeout(k) k = cTime = null fn(...ags) } }; return () => { if (cTime == null) { k = setTimeout(hyFn(...arguments), time) cTime = getTime() } else { if ( getTime() - cTime < 0) { // 清除之前的函数堆 ---- 重新记录 clearTimeout(k) k = null cTime = getTime() k = setTimeout(hyFn(...arguments), time) } }} }; export const contains = function(parentNode, childNode) { if (parentNode.contains) { return parentNode !== childNode && parentNode.contains(childNode) } else { // https://developer.mozilla.org/zh-CN/docs/Web/API/Node/compareDocumentPosition return (parentNode.compareDocumentPosition(childNode) === 16) } }; export const addClass = function (el, className) { if (typeof el !== "object") { return null } let classList = el['className'] classList = classList === '' ? [] : classList.split(/\s+/) if (classList.indexOf(className) === -1) { classList.push(className) el.className = classList.join(' ') } }; export const removeClass = function (el, className) { let classList = el['className'] classList = classList === '' ? [] : classList.split(/\s+/) classList = classList.filter(item => { return item !== className }) el.className = classList.join(' ') }; export const delay = ({fn, time}) => { let oT = null let k = null return () => { // 当前时间 let cT = new Date().getTime() const fixFn = () => { k = oT = null fn() } if (k === null) { oT = cT k = setTimeout(fixFn, time) return } if (cT - oT < time) { oT = cT clearTimeout(k) k = setTimeout(fixFn, time) } } }; export const position = (son, parent = global.document.body) => { let top = 0; let left = 0; let offsetParent = son; while (offsetParent !== parent) { let dx = offsetParent.offsetLeft; let dy = offsetParent.offsetTop; let old = offsetParent; if (dx === null) { return { flag: false } } left += dx; top += dy; offsetParent = offsetParent.offsetParent; if (offsetParent === null && old !== global.document.body) { return { flag: false } } } return { flag: true, top, left } }; export const getElem = (filter) => { return Array.from(global.document.querySelectorAll(filter)); }; export const elemOffset = (elem) => { return { width: elem.offsetWidth, height: elem.offsetHeight } };
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注创新互联行业资讯频道,感谢您对创新互联的支持。
文章名称:使用vue指令怎么实现气泡提示效果-创新互联
链接分享:http://www.jxjierui.cn/article/dspscp.html


咨询
建站咨询
