I have a Vue app which requests some html from an API that contains some blocks like <div class="play-video">...</div>
Calling the API with axios via a promise, it is inserted into the dom something like:
<div v-if="content" v-html="content"></div>
How can I bind click events to the children with the .play-video
class? Is it just a matter of watching for content
to change, and then running vanilla js query selectors to bind to them?
You can use some event delegation by adding a @click
handler and checking the target element using Element.closest()
new Vue({
el: "#app",
data: () => ({
content: null
}),
methods: {
handleClick(e) {
const elt = e.target.closest(".play-video");
if (elt) {
console.log("Got a click on .play-video or a child element")
}
}
},
mounted () {
// simulate loading content
setTimeout(() => {
this.content = `
<div>
<p>Some other element</p>
<button>I'm not part of <code>.play-video</code></button>
<div class="play-video">
<p><button>Click me, I am!</button></p>
</div>
</div>
`
}, 1000)
}
})
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<div id="app">
<div v-if="content" v-html="content" @click="handleClick"></div>
<p v-else>Loading...</p>
</div>
If you only want to catch click events on the .play-video
element itself and not any of its children, skip the .closest()
call and use
if (e.target.matches(".play-video") {
// ...
}
See https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#polyfill for browser compatibility and a polyfill if required.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With