user608684 user608684 - 4 months ago 117
jQuery Question

JavaScript methods and child elements in Vue.js

Vue.js is my first reactive library and I'm having trouble with methods and child elements. I suspect I'm missing something obvious.

In my example, the rendered listitems have method handlers for hover (mouseenter & mouseleave) events. Each listitem is a parent of a

<video>
element, paused by default. When the mouse enters a listitem, its child
<video>
plays (elem.play()). The video pauses when the mouse leaves the listitem.

Full example: https://jsfiddle.net/matbergman/hcgtkbwt/8/

<ul class="contentList">
<li v-for="item in items" v-on:mouseover="videoPlay()" v-on:mouseleave="videoPause()">
<video loop="loop" v-bind:src="item.video"></video>
<p>
{{item.description}}
</p>
</li>
</ul>

<script>

var vm = new Vue ({
el: ".contentList",
data: {
items: [
{
video : "http://206.130.101.116/misc/video01.mp4",
description : "Video 1"
},
{
video : "http://206.130.101.116/misc/video02.mp4",
description : "Video 2"
},
{
video : "http://206.130.101.116/misc/video03.mp4",
description : "Video 3"
}
]
},
methods: {
videoPlay: function() {
console.log("play");
vm.$el === document.getElementById('example')
// Play the child video, something like: this.getElementsByTagName("video")[0].play();

},
videoPause: function() {
console.log("pause");
// Pause the child video, something like: this.getElementsByTagName("video")[0].pause();
}
}

});

</script>


My method recognizes the mouse events. How do I apply the play() method to the child
<video>
? In jQuery it would be something like:

$("li").mouseenter(function() {
this.getElementsByTagName("video")[0].play();
});


But the scope of
this
is of course defined by my $el variable instead of the element with the attached event like I'm used to. Would the play() method be passed somehow as a property of a component?

Answer

Vue gives you access to the event object.

It gets passed implicitly when you supply only the method name:

<div @click="clickHandler">

... or can be passed explicitly using the $event variable:

<div @click="clickHandler($event)">

You can use the event's target to access the element that triggered the event. From there, you can access its children as you described. Here is an example using mouseenter and mouseleave:

new Vue ({
  el: ".contentList",

  methods: {
    videoPlay: function(event) {
      document.getElementById("consolelog").innerText = "play";
      event.currentTarget.getElementsByTagName("video")[0].play();

    },
    videoPause: function(event) {
      document.getElementById("consolelog").innerText = "pause";
      event.currentTarget.getElementsByTagName("video")[0].pause();
    }        
  }  

});
li {
  list-style:none;
  padding:1em;
  margin:2em;
  background-color:#f1f1f1;
}

li:hover {
  background-color:#ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.js"></script>
<ul class="contentList">
  <li  @mouseenter="videoPlay" @mouseleave="videoPause">
    <video loop="loop" src=""></video>
  </li>
</ul>

<div id="consolelog" style="position:fixed; top:10px; right:10px; background-color:#ffffcc; padding:5px;">
</div>

More about events can be found here in the Vue js guide.

Comments