Une fenêtre modale dynamique avec une vidéo YouTube ou Vimeo avec arrêt automatiquement à la fermeture de la fenêtre.
Faire une entête de type « hero » avec une vidéo HTML5 c’est super mais dur dur avec un iFrame. En d’autres mots, avec une vidéo YouTube ou Vimeo. La solution, se contenter d’un bouton et d’une fenêtre modale pour contenir le iFrame de la vidéo. Quoi de plus facile avec Bootstrap 5 :<!-- Le bouton (attention, retirer le « bs » pour la version Bootstrap 4 : <code>data-toggle</code> et <code>data-target</code>) --> <button type="button" class="btn" data-bs-toggle="modal" data-bs-target="#oModalYouTube"> Ouvrir la vidéo </button> <!-- La modale --> <div class="modal fade" id="oModalYouTube" tabindex="-1" aria-labelledby="oModalYouTubeTitre" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="oModalYouTubeTitre">Jean-Paul Riopelle</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button> </div> <div class="modal-body"> <div class="ratio ratio-16x9"> <iframe id="oVideoYouTubeiFrame" src="https://www.youtube.com/embed/WRKOwsIkwEY?html5=1" allowfullscreen></iframe> </div> </div> </div> </div> </div>
Noter l’utilisation des classes Bootstrap « ratio » et « ratio-16x9 » pour imbriquer une vidéo pleine grandeur, fluide tout en préservant les proportions. Petit truc, ajoutez le paramètre « html5=1 » au bout de l’adresse pour forcer une vidéo HTML5 au lieu d’un Flash. Ça fonctionne dans certains cas même si ça ne semble plus faire partie des paramètres officiels de YouTube. Mais qu’est-ce qu’on a à perdre pour quelques lettres supplémentaires ?
Gérer le playback
Outre les dimensions et les proportions du iFrame, il faut prévoir l’arrêt de la lecture (playback) lorsque la fenêtre se ferme. Et là encore, Bootstrap fait le travail, à l’aide des évènements JavaScript hide.bs.modal
et show.bs.modal
. Et c’est vraiment simple comme idée. Au lieu de se casser la tête à provoquer l’arrêt de la vidéo, dans ce cas-ci l’arrêt d’un objet vidéo Flash ou HTML5 dans un iFrame, le truc consiste à conserver l’adresse de la vidéo dans une variable puis de retirer carrément la vidéo du iFrame. De cette façon, la prochaine lecture devra charger à nouveau la vidéo (en fait la page) à partir de la variable. La vidéo se retrouvera au début et à l’arrêt :
<script> // Exemple en pur JavaScript (Vanilla) document.addEventListener('DOMContentLoaded', function() { var sUrlVideoAccueil = document.getElementById('oVideoYouTubeiFrame').getAttribute('src'); var oModalYouTubeElement = document.getElementById('oModalYouTube'); oModalYouTubeElement.addEventListener('hide.bs.modal', function (event) { document.getElementById('oVideoYouTubeiFrame').setAttribute('src', ''); }) var oModalYouTubeElement = document.getElementById('oModalYouTube'); oModalYouTubeElement.addEventListener('show.bs.modal', function (event) { document.getElementById('oVideoYouTubeiFrame').setAttribute('src', sUrlVideoAccueil); }) }); </script>
Note : Le fun avec Bootstrap 5, c’est qu’il n’est pas dépendant de jQuery. Mais si vous utilisez déjà jQuery, voilà l’équivalent :
<script> // Exemple jQuery $(document).ready(function(){ var url = $("#oVideoYouTubeiFrame").attr('src'); $("#oModalYouTube").on('hide.bs.modal', function(){ $("#oVideoYouTubeiFrame").attr('src', ''); }); $("#oModalYouTube").on('show.bs.modal', function(){ $("#oVideoYouTubeiFrame").attr('src', url); }); }); </script>
Automatisation
Maintenant, c’est bien beau une fenêtre modale statique si vous avez une seule vidéo. Mais si vous avez plusieurs vidéos à présenter, et même si Bootstrap ne permet qu’une seule modale à la fois, pourquoi ne pas dynamiser le tout à l’aide de paramètre data-*
!
<!-- Par exemple à l’aide d’un bouton du genre : --> <button type="button" class="cBtnYouTube btn" data-bs-toggle="modal" data-bs-target="#oModalYouTube" data-url="https://www.youtube.com/embed/WRKOwsIkwEY?html5=1" data-titre="Jean-Paul Riopelle" > Ouvrir la vidéo </button>
Et le code suivant :
<script> // Exemple en pur JavaScript (Vanilla) document.addEventListener('DOMContentLoaded', function() { var oModalYouTubeElement = document.getElementById('oModalYouTube') oModalYouTubeElement.addEventListener('hide.bs.modal', function (event) { document.getElementById('oModalYouTubeTitre').innerHTML = ''; document.getElementById('oVideoYouTubeiFrame').setAttribute('src', ''); }) }); window.addEventListener("DOMContentLoaded", function(e) { x = document.getElementsByClassName("cBtnYouTube"); var i; for (i = 0; i < x.length; i++) { x[i].addEventListener("click", function (event) { event.preventDefault(); document.getElementById('oModalYouTubeTitre').innerHTML = '<i class="fab fa-youtube"></i> '+this.getAttribute('data-titre'); document.getElementById('oVideoYouTubeiFrame').setAttribute('src', this.getAttribute('data-url')); }, false); } }, false); </script>
Code complet avec le iFrame parfait pour une vidéo YouTube
<!doctype html> <html lang="fr-CA"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Vidéo YouTube dans une fenêtre modal | Trucsweb.com</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous" /> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.2/css/all.css" /> </head> <body> <div class="bg-dark text-secondary px-4 py-5 text-center"> <div class="py-5"> <h1 class="display-5 fw-bold text-white">Vidéo YouTube dans une fenêtre modal</h1> <div class="col-lg-6 mx-auto"> <p class="fs-5 mb-4">Vidéo de Jean Paul Riopelle sur YouTube</p> <div class="d-grid gap-2 d-sm-flex justify-content-sm-center"> <button type="button" class="cBtnYouTube btn" data-bs-toggle="modal" data-bs-target="#oModalYouTube" data-url="https://www.youtube.com/embed/WRKOwsIkwEY?html5=1" data-titre="Jean-Paul Riopelle"><i class="fab fa-youtube fa-3x" style="color:#ff0000;"></i></button> </div> </div> </div> </div> <div class="modal fade" id="oModalYouTube" tabindex="-1" aria-labelledby="oModalYouTubeTitre" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered"> <div class="modal-content rounded-0"> <div class="modal-header rounded-0 border-0" style="color:#fff;background-color:#000"> <p id="oModalYouTubeTitre" class="modal-title lh-1"></p> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Fermer"></button> </div> <div class="modal-body p-0"> <div class="ratio ratio-16x9"> <iframe id="oVideoYouTubeiFrame" src="" allowfullscreen></iframe> </div> </div> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.bundle.min.js" integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf" crossorigin="anonymous"></script> <script> document.addEventListener('DOMContentLoaded', function() { var oModalYouTubeElement = document.getElementById('oModalYouTube') oModalYouTubeElement.addEventListener('hide.bs.modal', function (event) { document.getElementById('oModalYouTubeTitre').innerHTML = ''; document.getElementById('oVideoYouTubeiFrame').setAttribute('src', ''); }) }); window.addEventListener("DOMContentLoaded", function(e) { x = document.getElementsByClassName("cBtnYouTube"); var i; for (i = 0; i < x.length; i++) { x[i].addEventListener("click", function (event) { event.preventDefault(); document.getElementById('oModalYouTubeTitre').innerHTML = '<i class="fab fa-youtube"></i> '+this.getAttribute('data-titre'); document.getElementById('oVideoYouTubeiFrame').setAttribute('src', this.getAttribute('data-url')); }, false); } }, false); </script> </body> </html>
Références
- Bootstrap 3 and Youtube in Modal
- Paramètres du lecteur - YouTube API iFrame
- Modal Bootstrap 5
- YouTube
- Vimeo