Reputation: 7078
I need to trigger a mouseover in Vue, but only on an element and its children, but not its parent. According to documentation this should work with the .stop
modifier, but for some reason it still bubbles. .self
wont work on child elements.
Any ideas what I might be doing wrong?
The code is simple:
<div v-for="(element) in elements" :key="element.id" :class="element.states"
@mouseover.stop="element.states.hover = true"
@mouseleave.stop="element.states.hover = false"></div>
Or on a component:
<my-component v-for="(element) in elements" :key="element.id" :class="element.states"
@mouseover.native.stop="element.states.hover = true"
@mouseleave.native.stop="element.states.hover = false"></my-component>
Upvotes: 1
Views: 4507
Reputation: 7078
After some extensive testing and try&error I found the reason why it was not working:
Due to the DOM nesting the mouseleave
event is not fired, when hovering over a child. Also thanks @Shoejep for the test with logging, where you can see this behaviour.
To fix it, I had to use mouseout
event on the children which gets fired on the parent when entering a child.
Upvotes: 1
Reputation: 4839
I've created a simple snippet to show how you can use @mouseover and @mouseleave with the stop event modifier and it seems to work, i.e. you only see BodyOver and BodyLeave in the console when entering and leaving the outer element.
new Vue({
el: "#app",
data: () => {
return {
parents: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
}
},
methods: {
over(ev) {
console.log(`Over ${ev.target.classList[0]}`);
},
leave(ev) {
console.log(`Leave ${ev.target.classList[0]}`);
},
bodyOver(ev) {
console.log(`Body Over ${ev.target.classList[0]}`);
},
bodyLeave(ev) {
console.log(`Body Leave ${ev.target.classList[0]}`);
}
}
});
.body {
padding: 20px;
background: red;
}
.parent {
padding: 20px;
background: green;
}
.child {
padding: 20px;
background: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="body" @mouseover="bodyOver" @mouseleave="bodyLeave">
Body
<div class="parent" @mouseover.stop="over" @mouseleave.stop="leave" v-for="parent in parents">
Parent
<div class="child">
Child
</div>
</div>
</div>
</div>
Upvotes: 1