Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

addEventListener inside Vue-Component with vanilla JS

It seems that vanilla eventListeners don't work when referencing dom-objects inside vue-components.

Markup

<p id="test1">Hover this (works)</p>
<div id="app">
    <p id="test2">Hover this (not working)</p>
</div>

JS

document.querySelector('#test1').addEventListener('mouseover', function() {
    alert("HOVER1")
})

document.querySelector('#test2').addEventListener('mouseover', function() {
    alert("HOVER2")
})

new Vue({
    el: "#app"
})

Live-Example

https://jsfiddle.net/seltsam23/dq7euos0/

Is this behaviour intended? Are there any other limitations when combining vanilla-js with vue?

like image 692
Seltsam Avatar asked Jan 28 '23 09:01

Seltsam


1 Answers

Actually, the only one that is not working is the example with alert("HOVER2") and it's because Vue content is dynamically rendered, so when your script loads, the element to which you want to add the event listener might not be there yet.

If you want it to work, you would need to move it to mounted hook:

new Vue({
  el: "#app",
  mounted() {
    document.querySelector('#test2').addEventListener('click', function() { alert("HOVER2") })
  }
})

Or you could use a little trick by putting your querySelector inside of setTimeout(() => ..., 0) which will push it to the end of the task queue and run it when all other queued tasks are finished:

setTimeout(() => document.querySelector('#test2').addEventListener('click', function() { alert("HOVER2") }), 0);

However, you should use Vue's built-in events and avoid doing direct DOM manipulations, because Vue discards whatever you've done to DOM and updates it with it's virtual DOM on next update tick. In this case it doesn't result in anything critical, but since Vue has it's own event handlers, you should use them.

like image 89
dziraf Avatar answered Jan 29 '23 21:01

dziraf