10

I have a selection of video thumbnails that I want to trigger to play/pause on hover. I have managed to get one of them to work, but I run into a problem with the others on the list. Attached is the fiddle of my code. There will be a div covering each html5 video so the hover needs to delegate to the video, which I'm unsure as to how to do.

https://jsfiddle.net/meh1aL74/

Preview of the html here -

<div class="video">
            <div class="videoListCopy">
                <a href="videodetail.html" class="buttonMore">
                        <div class="breaker"><div class="line"></div></div>
                        <div class="buttonContent">
                            <div class="linkArrowContainer">
                                <div class="iconArrowRight"></div>
                                <div class="iconArrowRightTwo"></div>
                            </div>
                            <span>Others</span>
                        </div>
                    </a>
            </div>
            <div class="videoSlate">
                <video class="thevideo" loop>
                  <source src="http://www.w3schools.com/html/movie.ogg" type="video/ogg">
                Your browser does not support the video tag.
                </video>
            </div>
        </div>
         
         
          <div class="video">
            <div class="videoListCopy">
                <a href="videodetail.html" class="buttonMore">
                        <div class="breaker"><div class="line"></div></div>
                        <div class="buttonContent">
                            <div class="linkArrowContainer">
                                <div class="iconArrowRight"></div>
                                <div class="iconArrowRightTwo"></div>
                            </div>
                            <span>Others</span>
                        </div>
                    </a>
            </div>
            <div class="videoSlate">
                <video class="thevideo" loop>
                  <source src="http://www.w3schools.com/html/movie.ogg" type="video/ogg">
                Your browser does not support the video tag.
                </video>
            </div>
        </div>

Preview of the JavaScript here -

    var figure = $(".video");
    var vid = $("video");

    [].forEach.call(figure, function (item) {
            item.addEventListener('mouseover', hoverVideo, false);
            item.addEventListener('mouseout', hideVideo, false);
    });
    
    function hoverVideo(e) {  
            $('.thevideo')[0].play(); 
    }

    function hideVideo(e) {
            $('.thevideo')[0].pause(); 
    }

Thank you very much for your help.

Syscall
  • 19,327
  • 10
  • 37
  • 52
Oliver Chalmers
  • 117
  • 1
  • 1
  • 6

5 Answers5

32

Shortest version would be this one. No need for any fancy jQuery, just plain HTML:

<div>
    <video onmouseover="this.play()" onmouseout="this.pause();this.currentTime=0;">
    <source src="yourVideo.ogg" type="video/ogg"></source>
    </video>    
</div>

This way it's a tad cleaner.

Emil Hovhannisyan
  • 566
  • 1
  • 6
  • 17
12

Why are you uisng native event binding together with jQuery ?

Anyway, if you want to handle the events natively you can use the .bind method and pass the index of each video to the handlers

var figure = $(".video");
var vid = figure.find("video");

[].forEach.call(figure, function (item,index) {
    item.addEventListener('mouseover', hoverVideo.bind(item,index), false);
    item.addEventListener('mouseout', hideVideo.bind(item,index), false);
});

function hoverVideo(index, e) {
    vid[index].play(); 
}

function hideVideo(index, e) {
    vid[index].pause(); 
}

Demo at http://jsfiddle.net/gaby/0o8tt2z8/2/


Or you can go full jQuery

var figure = $(".video").hover( hoverVideo, hideVideo );

function hoverVideo(e) { $('video', this).get(0).play(); }
function hideVideo(e) { $('video', this).get(0).pause(); }

Demo at http://jsfiddle.net/gaby/0o8tt2z8/1/

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
  • Thanks alot Gaby, this is perfect. – Oliver Chalmers Nov 06 '14 at 12:30
  • @OliverChalmers, your are welcome. (*also updated answer and removed the `console.log` command i had left in there, and used the variable vid instead of searching for the videos in each hover*) – Gabriele Petrioli Nov 06 '14 at 12:31
  • Your answer is really helpful. I have used the jQuery part of your solution in my question - https://stackoverflow.com/questions/53585355/play-multiple-plyr-vimeo-embeds-on-hover. It would be great to get your input if you have time. – Alex Ljamin Dec 02 '18 at 23:14
  • 1
    The video only sometimes resumes playing for me (OSX/Chrome 75.0.3770.142) - you need to click outside of the video before hovering back over it to resume playing. Any ideas what might be going on? A focus issue? – iamkeir Jul 24 '19 at 12:00
1

The hoverVideo() function specifically calls for the first instance of .thevideo, so hovering over either one will play the first video.

You have to grab the element that the event occurred on, then find the .thevideo element within that element:

var figure = $(".video");
var vid = $("video");

[].forEach.call(figure, function (item) {
  item.addEventListener('mouseover', hoverVideo, false);
  item.addEventListener('mouseout', hideVideo, false);
});

function hoverVideo(e) {
  $(this).find('.thevideo')[0].play();
}

function hideVideo(e) {
  $(this).find('.thevideo')[0].pause();
}

Here's an updated fiddle: http://jsfiddle.net/52mxdbgy/1/

Shawn Erquhart
  • 1,820
  • 2
  • 17
  • 30
  • Thanks Shawn for your swift reply. I realize that is what is happening, hence the question as to how I go about setting it up for each video as opposed to just the first. Any ideas ? :) – Oliver Chalmers Nov 06 '14 at 12:00
1

Here the same without jQuery and with a bit ES6. ;)

for(let tupel of document.querySelectorAll('video')) {
  tupel.addEventListener('mouseover', (e) => {
    e.target.play()
  }, false);

  tupel.addEventListener('mouseout', (e) => {
    e.target.pause()
  }, false);
}
teawithfruit
  • 767
  • 1
  • 11
  • 22
0

Your function explicitly asks for the first video: $('.thevideo')[0].play(); (first element in array).

Therefore, you need to (at least) pass the index of the video to which you bind the actions to ensure the right video gets played and paused.

For example:

$(document).ready(function() {       
    $('.video').each(function(i, obj) {
        $(this).on("mouseover", function() { hoverVideo(i); });
        $(this).on("mouseout", function() { hideVideo(i); });
    });
});

function hoverVideo(i) {  
    $('.thevideo')[i].play(); 
}

function hideVideo(i) {
    $('.thevideo')[i].pause(); 
}

Where I use jQuery's .on() method so all methods are jQuery (instead of a mix with JavaScript).

You can see this in action in the following jsFiddle:

DEMO

Community
  • 1
  • 1
Jean-Paul
  • 19,910
  • 9
  • 62
  • 88