web-dev-qa-db-fra.com

Comment puis-je ajouter des vidéos en un clic à mes vidéos HTML5 sans interférer avec les contrôles natifs?

J'utilise le code suivant pour ajouter une fonctionnalité de lecture en un clic à la vidéo HTML5:

$('video').click(function() {
  if ($(this).get(0).paused) {
    $(this).get(0).play();
  }
  else {
    $(this).get(0).pause();
  }
});

Cela fonctionne bien, sauf que cela interfère avec les commandes natives du navigateur: en d’autres termes, il est capturé lorsqu'un utilisateur clique sur le bouton pause/lecture, inversant immédiatement sa sélection et rendant le bouton pause/lecture inefficace.

Existe-t-il un moyen de sélectionner uniquement la partie vidéo du DOM ou, à défaut, de capturer les clics sur la partie controls du conteneur vidéo, afin que je puisse ignorer/inverser le clic fonctionnalité de lecture lorsqu'un utilisateur appuie sur le bouton pause/lecture?

16
user113292

Vous pouvez ajouter une couche au-dessus de la vidéo qui capture l'événement click. Cachez ensuite ce calque pendant la lecture de la vidéo.

Le balisage (simplifié):

<div id="container">
    <div id="videocover">&nbsp;</div>
    <video id="myvideo" />
</div>

Le scénario:

$("#videocover").click(function() {
    var video = $("#myvideo").get(0);
    video.play();

    $(this).css("visibility", "hidden");
    return false;
});

$("#myvideo").bind("pause ended", function() {
    $("#videocover").css("visibility", "visible");
});

Le CSS:

#container {
    position: relative;
}

/*
    covers the whole container
    the video itself will actually stretch
    the container to the desired size
*/
#videocover {
    position: absolute;
    z-index: 1;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}
17
Torsten Walter

Je sais que c’est une vieille question, mais j’ai rencontré le même problème et j’ai trouvé une autre solution! Mais comme l'affiche originale, j'ai eu des problèmes avec les commandes. Résolu le problème avec jQuery comme ceci:

$("video").click(function (e) {
    if(e.offsetY < ($(this).height() - 36)) // Check to see if controls where clicked
    {
        if(this.paused)
            this.play();
        else
            this.pause();
    }
});

Je vérifie le décalage dans le clic et s'il est au-dessus des commandes, mes fonctions de lecture/pause ne font rien.

4
Kristofer Källsbo

Vous pouvez essayer event.stopPropagation et voir si cela fonctionne. Bien que je pense que cela empêcherait les contrôles natifs de fonctionner ou ne ferait rien du tout.

$('video').click(function(event) {
  event.stopPropagation();
  if ($(this).get(0).paused) {
    $(this).get(0).play();
  }
  else {
    $(this).get(0).pause();
  }
});

Si le navigateur considère que les contrôles natifs et la vidéo font tous partie du même élément (et je crois qu'ils le font), vous aurez probablement de la chance. event.target de jQuery ne vous permettrait pas de faire la différence entre un clic sur la vidéo et un clic sur les commandes.

Donc, je pense que votre meilleure option est de construire vos propres contrôles (ancien tutoriel, toujours assez simple). Ou demandez aux développeurs de navigateur de cliquer sur la lecture/pause de la vidéo lorsque les contrôles sont activés. On dirait qu'il devrait le faire par défaut.

3
heff

Excellentes réponses ici. Merci pour ceux-ci. Voici un truc que j'ai découvert pour rendre les contrôles cliquables, tous jQuery .

$('#video_player').click(function(e){

    var y = e.pageY - this.offsetTop;

    //Subtract how much control space you need in y-pixels.
    if(y < $(this).height() - 40) 
    {
        //$(this).get(0).play();
        //... what else?
    }

});
1
sampoh

La solution de Torsten Walter fonctionne bien et c'est une solution assez élégante au problème, et c'est probablement la meilleure façon de le gérer, même s'il ne gère pas le clic à la pause. Cependant, sa solution m'a fait réfléchir à un moyen hacky de le faire, et j'ai proposé ceci:

Markup

<div id="container">
  <div id="videocover">&nbsp;</div>
  <video id="myvideo" />
</div>

JavaScript

$('#videocover').click(function(event) {
  var video = $('#myvideo')[0];
  if (video.paused) {
    video.play();
  }
  else {
    video.pause();
  }
  return false;
});

CSS

#container {
  position: relative;
}

#videocover {
  position: absolute;
  z-index: 1;
  height: 290px; /* Change to size of video container - 25pxish */
  top: 0;
  right: 0;
  bottom: 0;
  left;
}

Fondamentalement, il garde la couverture cliquable en permanence pour gérer la fonctionnalité clic-pour-jouer/cliquez-pour-mettre en pause, mais veille à ce que la couverture ne chevauche pas les contrôles au bas de la vidéo.

Ceci est, bien sûr, un kludge, comme cela:

  • suppose que tous les navigateurs placent les contrôles dans la même zone et que les contrôles ont la même hauteur
  • nécessite de spécifier la hauteur du conteneur vidéo en CSS
  • empêche les contrôles d'apparaître lorsque la souris survole la vidéo

Mais je me suis dit que je le mettrais là-bas.

0
user113292