![](/img/trans.png)
[英]How to close outer v-tooltip on inner v-tooltip when there are many containers
[英]Keep v-tooltip open when hovering over the tooltip
首先,术语,“链接”是鼠标进入的区域。 “工具提示”是弹出并显示额外信息的东西。 --- 以上添加于 2020-04-29
我正在使用 Vuetify 并试图在鼠标悬停在“工具提示”上时保持 v-tooltip 保持打开状态。 工具提示中的内容将会很丰富,并且不希望在访问者查看它时自动隐藏。
<template>
<v-tooltip
v-model="show"
max-width="600px"
content-class="link-tooltip-content"
bottom>
<template v-slot:activator="{ on }">
<div
:style="boxStyle"
@mouseover="mouseover"
@mouseleave="mouseleave"
></div>
</template>
<template v-slot:default>
<v-card
@mouseover="mouseover"
@mouseleave="mouseleave"
>
<v-row dense>
<v-col>
<v-card-title class="headline">
rich tooltip
</v-card-title>
</v-col>
</v-row>
</v-card>
</template>
</v-tooltip>
</template>
<script>
export default {
data: () => ({
show: false,
hoverTimer: null
}),
methods: {
boxStyle: function() {
return {
left: "100px",
top: "100px",
width: "100px",
height: "100px",
position: "absolute"
};
},
mouseover: function() {
console.log(`mouseover`);
this.show = true;
clearTimeout(this.hoverTimer);
},
mouseleave: function() {
console.log(`mouseleave`);
this.hoverTimer = setTimeout(() => {
this.show = false;
}, 3000);
}
}
};
</script>
但这不起作用。 激活器槽(“链接”)元素上的 mouseover 和 mouseleave 事件处理程序会触发,但默认槽(“工具提示”)上的事件处理程序不会触发。
我认为原因是,因为“工具提示”内的内容被移动到了 body 标签下的其他地方。
问题是,当悬停在“工具提示”上时,如何保持打开状态。
我像这样移动鼠标:
我正在考虑在工具提示上添加一个 mouseenter 事件,以便我可以clearTimeout(hoverTimer)
并保持工具提示打开。
我知道 9 年前有一个类似的问题,使用 jQuery 鼠标悬停时保持工具提示打开,但如果可能的话我不想使用 jQuery 。 我更喜欢 Vue 的方式。
这是一个可重复的小例子: https://www.codeply.com/p/GuFXqAAU8Y
我建议您使用v-menu
并将open-on-hover
道具设置为true
,而不是使用v-tooltip
。 如果您必须轻推您在菜单中放置的任何内容,请确保设置适当的close-delay
值,以便菜单在用户到达之前不会关闭。
示例: https://codepen.io/stephane303/pen/WNwdNxY
<v-menu open-on-hover right offset-x nudge-right="20" close-delay="100">
.v-tooltip__content
在vuetify.min.css
中设置了pointer-events:none
。 如果将其设置回auto
,则允许将其悬停。
当其悬停时,其父级悬停。 当它的父级悬停时,它有一个工具提示。 所以你只需要:
.v-tooltip__content {
pointer-events: auto;
}
为此,我制作了 VTooltip 的扩展版本。 只需通过interactive
道具。 通过将“创建者”悬停在列表项中查看工作示例: https://tzkt.io/KT1RJ6PbjHpwc3M5rw5s2Nbmefwbuwbdxton/tokens
<script>
/**
* Extends VTooltip with interactivity
* @see https://material-ui.com/components/tooltips/#interactive
*/
import { VTooltip } from 'vuetify/lib';
export default {
extends: VTooltip,
props: {
interactive: {
type: Boolean,
default: false,
},
closeDelay: {
type: [Number, String],
default: 50,
},
},
computed: {
// I'm not 100% sure in this, but it works
calculatedLeft() {
const originalValue = VTooltip.options.computed.calculatedLeft.call(this);
if (!this.interactive) return originalValue;
const { left, right } = this;
let value = parseInt(originalValue);
if (left || right) {
value += right ? -10 : 10;
}
return `${value}px`;
},
calculatedTop() {
const originalValue = VTooltip.options.computed.calculatedTop.call(this);
if (!this.interactive) return originalValue;
const { top, bottom } = this;
let value = parseInt(originalValue);
if (top || bottom) {
value += bottom ? -10 : 10;
}
return `${value}px`;
},
styles() {
const originalValue = VTooltip.options.computed.styles.call(this);
if (!this.interactive) return originalValue;
const {
top, bottom, left, right,
} = this;
let paddingDirection;
if (bottom) paddingDirection = 'top';
else if (top) paddingDirection = 'bottom';
else if (right) paddingDirection = 'left';
else if (left) paddingDirection = 'right';
return {
...originalValue,
[`padding-${paddingDirection}`]: `${10}px`,
};
},
},
methods: {
onTooltipMouseenter(e) {
if (this.interactive) {
this.clearDelay();
this.isActive = true;
}
this.$emit('tooltip:mouseenter', e);
},
onTooltipMouseleave(e) {
if (this.interactive) {
this.clearDelay();
this.runDelay('close');
}
this.$emit('tooltip:mouseleave', e);
},
genContent() {
const content = this.$createElement('div', this.setBackgroundColor(this.color, {
style: this.contentStyles,
staticClass: 'v-tooltip__content',
class: {
[this.contentClass]: true,
menuable__content__active: this.isActive,
},
}), this.getContentSlot());
return this.$createElement('div', {
style: this.styles,
attrs: this.getScopeIdAttrs(),
class: {
'v-tooltip__wrapper': true,
'v-tooltip__wrapper--fixed': this.activatorFixed,
},
directives: [{
name: 'show',
value: this.isContentActive,
}],
on: {
mouseenter: this.onTooltipMouseenter,
mouseleave: this.onTooltipMouseleave,
},
ref: 'content',
}, [content]);
},
genActivatorListeners() {
const listeners = VTooltip.options.methods.genActivatorListeners.call(this);
if (this.interactive) {
if (listeners.mouseenter) {
listeners.mouseenter = (e) => {
this.getActivator(e);
this.clearDelay();
if (!this.isActive) {
this.runDelay('open');
}
};
}
}
return listeners;
},
},
};
</script>
<style lang="scss">
.v-tooltip__wrapper {
position: absolute;
&--fixed {
position: fixed;
}
.v-tooltip__content {
position: static;
}
}
</style>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.