AngularJS script is running twice - javascript

I'm building a script that autoplays a video when a Bootstrap modal opens. I'm using a ng-click on the modal open form, which runs a jquery script withing the angularjs controller.
$scope.startVideo = function (id) {
$(window).on('shown.bs.modal', function() {
console.log('Id nu is: '+id);
var v = document.getElementById("player"+id);
v.play();
console.log('Now playing: player'+id);
});
}
It works fine at first. But when I close the first modal (and stop the video), and fire the script again on another modal, the first video starts, and the second video starts. So now I have 2 video's playing.
The console is giving back: :
Now playing: player1
Now playing: player1
Now playing: player2
The part of the modal which might be interesting:
<div class="modal-body">
{{video.subheader}}<br>
<video id="player{{video.id}}" width="100%" height="100%" controls>
<source src="{{video.videourl+video.ext}}" type="video/mp4></source>
</video>
</div>
<!-- Popup modals below -->
<div id="videomodal{{video.id}}" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">{{video.header}}</h4>
</div>
<div class="modal-body">
{{video.subheader}}<br>
<video id="player{{video.id}}" width="100%" height="100%" controls>
<source src="{{video.videourl+video.ext}}" type="video/mp4"></source>
</video>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Why is the script running twice? I need it to run once when the modal opens. And when I stop the video, close the modal and open another modal, the other modal should start. Not both.

A quick guess would be that your event listeners aren't listening for shown.bs.modal from a specific modal but from any modal on the page. Assuming each modal has its own id (or data attribute or something) based on the id of the video (if they don't have ids you could use the jQuery :has selector - :has('#player'+id) - or something along those lines)
$scope.startVideo = function (id) {
$(window).on('shown.bs.modal', '<modal specific selector>', function() {
console.log('Id nu is: '+id);
var v = document.getElementById("player"+id);
v.play();
console.log('Now playing: player'+id);
});
}

Related

Is there a way I can make a HTML5 video display a div at a specific point in the video?

I want to get a popup to appear when a HTML5 video gets to a certain point, for example; 34 seconds into the video...
I have the popup in a div and I just need to find a way to make it only appear once the video has hit a specific time mark. I can't have it just time how long the user is on the page though... (which makes it a bit harder....!) it has to be from the video is played.
Is this somehow possible?
<video class="fs-video" preload="auto" >
<source class="fs-video" src="videos/scene1_option1a.mp4" type="video/mp4" >
</video>
Thanks!
The video tag as a property called "currentTime" which returns (or sets) the playback position in seconds. So I think the best course of action would be a javascript setInterval function that continuously checks that property, and fires when the time is 34:
setInterval (function(){
var curTime = document.getElementById("vidId").currentTime;
if (curTime == 34) {
document.getElementById("divId").style.visibility = "visible"
}
},500);
<video id="vidId"></video>
<div id="divId" style="visibility:hidden;"></div>
Use timeupdate event which runs when video progress. But it triggers at each update so to solve that maintain a flag and check if popup is already shown
Here's a demo for 6 seconds
var popupShown = false
var vid = document.getElementById("myVideo");
vid.addEventListener('timeupdate', function(e) {
if ((e.target.currentTime > 6) && !popupShown) {
$('#myModal').modal('show');
popupShown = true;
}
});
<!DOCTYPE html>
<html>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<body>
<video class="fs-video" preload="auto" id="myVideo" controls>
<source class="fs-video" src="https://www.w3schools.com/tags/mov_bbb.mp4" type="video/mp4" >
</video>
<!-- Modal -->
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Video is at 6 seconds.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</body>
</html>

How to stop Vimeo video when Bootstrap modal is dismissed?

I have a Vimeo modal that works wonderfully and - after some effort - I've gotten the video to stop when the modal is closed via the 'X' button. However, since I put the close function on the 'X' button, if the user clicks away from the video to close the modal rather than using the button, the video keeps playing.
Here is the HTML where I call the stopVideo() function with onclick:
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="stopVideo()">
<span aria-hidden="true">×</span>
</button>
</div>
And here is the Javascript function that stops the video:
<script>
function stopVideo(){
var $frame = $('iframe#nofocusvideo');
// saves the current iframe source
var vidsrc = $frame.attr('src');
// sets the source to nothing, stopping the video
$frame.attr('src','');
// sets it back to the correct link so that it reloads immediately on the next window open
$frame.attr('src', vidsrc);
}
</script>
So, how can I alter the function to apply not to the specific close button, but to any instance where the modal loses focus such as clicking away from the video?
I'm a novice, so go easy on me. Thanks in advance!
EDIT 1:
I've changed the script to the following:
<script>
function stopVideo(){
var $frame = $('iframe#nofocusvideo');
// saves the current iframe source
var vidsrc = $frame.attr('src');
// sets the source to nothing, stopping the video
$frame.attr('src','');
// sets it back to the correct link so that it reloads immediately on the next window open
$frame.attr('src', vidsrc);
}
$('#promo-video').on('hidden.bs.modal', function (e) {
stopVideo();
})
</script>
The stopVideo() function is not being called. Any idea what I'm doing wrong?
EDIT 2:
Here's the code for the modal in question:
<!-- VIDEO MODAL -->
<div class="modal fade" id="promo-video" tabindex="-1" role="dialog" aria-labelledby="modal-video-label">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="stopVideo()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="modal-video">
<div class="embed-responsive embed-responsive-16by9">
<iframe id="nofocusvideo" src="https://player.vimeo.com/video/180565514?api=1&player_id=vimeoplayer" name="vimeoplayer" width="640" height="360" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- End Video Modal -->
Here's the working code for it using the default bootstrap id's. Not too sure why yours isn't working.
function stopVideo() {
var $frame = $('iframe#nofocusvideo');
// saves the current iframe source
var vidsrc = $frame.attr('src');
// sets the source to nothing, stopping the video
$frame.attr('src', '');
// sets it back to the correct link so that it reloads immediately on the next window open
$frame.attr('src', vidsrc);
}
$('#myModal').on('hidden.bs.modal', function(e) {
stopVideo();
})
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body">
<iframe id="nofocusvideo" src="https://player.vimeo.com/video/182738685" width="640" height="360" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
A solution that work for me is reload the modal contents:
$("#modal-video").on("hidden.bs.modal", function () {
var url = $('#video-frame').attr('src');
$('#video-frame').attr('src', '');
$('#video-frame').attr('src', url);
});
After a lot of trial and error, changing the javascript to the following solved my problem:
<script>
( function($) {
function iframeModalOpen(){
$('.modalButton').on('click', function(e) {
var src = $(this).attr('data-src');
var width = $(this).attr('data-width') || 640;
var height = $(this).attr('data-height') || 360;
var allowfullscreen = $(this).attr('data-video-fullscreen');
$("#promo-video iframe").attr({
'src': src,
'height': height,
'width': width,
'allowfullscreen':''
});
});
$('#promo-video').on('hidden.bs.modal', function(){
$(this).find('iframe').html("");
$(this).find('iframe').attr("src", "");
});
}
$(document).ready(function(){
iframeModalOpen();
});
} ) ( jQuery );
</script>
I have a series of vimeo player in modal and finally figured out a dynamic way to stop the video after closing the modal. Seriously, bootstrap/vimeo should add this as default!!
$('.modal').on('hidden.bs.modal', function () {
var $this = $(this);
//get iframe on click
var vidsrc_frame = $this.find("iframe");
var vidsrc_src = vidsrc_frame.attr('src');
console.log(`videosrc=` + vidsrc_src);
vidsrc_frame.attr('src', '');
vidsrc_frame.attr('src', vidsrc_src);
});
Have a nice day!
This option is better and dynamic
$(function(){
$('.modal, .close').click(function(){
$("iframe").each(function() {
var src= $(this).attr('src');
$(this).attr('src',src);
});
});
});

Stop YouTube video on modal close - after AJAX load

I have a small script that stops YouTube videos from playing after their modals are closed. The issue is it doesn't work if the HTML has been loaded via AJAX.
Script:
$('#panelModal-1').on('hidden.bs.modal', function () {
callPlayer('yt-player-1', 'stopVideo');
});
$('#panelModal-2').on('hidden.bs.modal', function () {
callPlayer('yt-player-2', 'stopVideo');
});
HTML (curly braces denote data pulled from CMS):
<li>
<a href="#" title="Watch Video" data-toggle="modal" data-target="#panelModal-{count}">
<div class="video-background" style="background-image:url(http://img.youtube.com/vi/{video_youtube_id}/hqdefault.jpg)"></div>
<div class="video-details">
<h4>{title}</h4>
<p>{video_subtitle}</p>
</div>
</a>
<!-- Modal -->
<div class="modal fade" id="panelModal-{count}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel-{count}">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel-{count}">{title}</h4>
</div>
<div class="modal-body">
<div id="yt-player-{count}" class="embed-responsive embed-responsive-16by9">
<iframe class="embed-responsive-item" src="https://www.youtube.com/embed/{video_youtube_id}?enablejsapi=1"></iframe>
</div>
</div>
</div>
</div>
</div>
</li>
The AJAX part is this:
$(document).ready(function()
{
$('.sub-nav').delegate('.load-case-studies', 'click', function(e)
{
// Don't follow the link
e.preventDefault();
$('.sub-nav a').removeClass('active');
$(this).addClass('active');
// Fetch the next page
$.get($(this).attr('href'), function(data)
{
// Only grab the part of the page we want
content = $(data).find('.ajax-wrapper').hide();
// Add it to the DOM
$(content).replaceAll('#entry-container');
// Fade-in our new content
$(content).fadeIn('fast');
});
});
});
How can I get the videos to stop playing after the modal is closed, if the data has been loaded via AJAX?
you can use following jQuery command.
$('#playerID').get(0).stopVideo();
If your using Player API :
var player = new YT.Player('player');
player.stopVideo();

Adding on click events to IFrame which opens a modal

I am currently developing a div that will contain up to 4 Media type divs. The media types include images, PDFs, and Youtube videos. The code I currently have running creates the divs as imgs if possible. If it is not possible(youtube videos/pdfs) it opens them as IFrames. As of now, the user is able to click on the imgs which launches a modal. However, I am unable to to get the IFrames to show the modal.Here is my code HTML - Modal
<!-- Modal -->
<div id="mediaModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">title</h4>
</div>
<div class="modal-body">
<p>here would be the description</p>
</div>
<div class="modal-media">
<p>here is the media</p>
</div>
<div class="modal-footer">
<p>here would be the credits
</div>
</div>
</div>
</div>
Here is my javascirpt
//this creates img/iframes dynamcially and throws them into a media-container div
var source = null;
//if it is not a youtube video/pdf/txt, put it in a img tag
if( null == ( media[1].match(/pdf/i) || media[1].match(/txt/i) || media[1].match(/youtube.com/) ) )
{
source = "<img data-toggle='modal' data-target='#mediaModal' id='m" + i + "'src='"+ media[1] + "'<img>";
}
else //throw it in a iframe tag
{
source = "<iframe data-toggle='modal' data-target='#mediaModal' class='modz' id='m" + i + "'src='"+ media[1] + "'></iframe>";
}
var div = $(source);
$("#media-container").append(div);
I tried adding a class to the iFrame and adding an onClick method, but it does not seem like the IFrame is picking up a click.
//opens a modal box for IFrame media.
$(".modz").on("click", function(e){
console.log("BING");
$("#mediaModal").modal('show');
});
Any help would be awesome. Thank you!
You can find your answer by folowing the step in this answer:
stackoverflow.com adding-click-event-handler-to-iframe

Wordpress Injected youtube videos, play on modal open, pause on modal close

I have youtube videos being injected dynamically with wordpress into multiple modals.
<div class="modal-overlay features-modal" id="modal-<?php echo $do; ?>">
<div class="modal-bg">
<div class="modal-close"></div>
<div class="modal">
<div class="videoWrapper">
<iframe class="youtube-video" src="<?php the_sub_field('youtube_video') ?>?rel=0&controls=0&showinfo=0" frameborder="0" allowfullscreen allowscriptaccess="always"></iframe>
</div>
</div>
</div>
</div>
What I am trying to accomplish is to get each individual youtube video to play on modal open and pause on modal close. Right now I can get the video to pause on close, but when I try to implement play on open with autoplay=1, it plays again on close (this code does not reflect the play on click).
function modalFadeOut() {
$('.open-modal').fadeOut("fast").removeClass("open-modal");
$('html').css('overflow','');
};
// features scroll video modal
$(".video-button").click(function() {
var Modal = $(this).data("modal-type");
$("#"+Modal).fadeIn("fast").addClass("open-modal");
});
$('.modal-bg').click(function() {
modalFadeOut();
var vid = $(this).find('iframe[src*="youtube"]');
if ( vid.length > 0 ) {
var src = vid.attr('src');
vid.attr('src', '');
vid.attr('src', src);
}
});

Categories