Twitter Bootstrap Modal stop Youtube video - javascript

I'm very new to javascript and trying to use Twitter bootstrap to get a good looking website up and running quickly. I know this has something to do with jquery, but I'm not sure how to stop my video when I push the close button or the close icon.
Can someone explain how I can get my video to stop playing because even when I close the window, I can still hear it in the background.
<!-- Button to trigger modal -->
<img src="img/play.png">
<!-- Modal -->
<div id="myModal" class="modal hide fade" tabindex="-1" role=labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria>×</button>
<h3 id="myModalLabel">I am the header</h3>
</div>
<div class="modal-body">
<p><iframe width="100%" height="315" src="http:com/embed/662KGcqjT5Q" frameborder="0" allowfullscreen></iframe></p>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
</div>
</div>

I know I'm 2+ years late, but since then, a couple of things have changed, with B3 the new way to perform this out of the box is this:
$("#myModal").on('hidden.bs.modal', function (e) {
$("#myModal iframe").attr("src", $("#myModal iframe").attr("src"));
});
Have fun with Bootstrap!

There is a nice proper way of doing this - see the comments in the approved answer to this post.
Couldn't get that working first time round myself though, and was in a rush, so I did a rather horrible hacky bit of code which does the trick.
This snippet 'refreshes' the src of the embed iframe, causing it to reload:
jQuery(".modal-backdrop, #myModal .close, #myModal .btn").live("click", function() {
jQuery("#myModal iframe").attr("src", jQuery("#myModal iframe").attr("src"));
});

If someone still has the problem, try this, it worked for me:
$(document).ready(function(){
$('.modal').each(function(){
var src = $(this).find('iframe').attr('src');
$(this).on('click', function(){
$(this).find('iframe').attr('src', '');
$(this).find('iframe').attr('src', src);
});
});
});

Here is a simple way I've found for having a video play in a modal window, and then stop playing on close.
Use the .html to load the iFrame with your video into the modal-body, when the modal is shown, and then replace the modal-body with nothing when it is hidden.
$('#myModal').on('show', function () {
$('div.modal-body').html('YouTube iFrame goes here');
});
$('#myModal').on('hide', function () {
$('div.modal-body').html('');
});
Here is a jsfiddle example:
http://jsfiddle.net/WrrM3/87/

Here, I generalize #guillesalazar's answer.
This will reset any iFrame within any bootstrap modal (when the modal is closed):
$(function(){
$("body").on('hidden.bs.modal', function (e) {
var $iframes = $(e.target).find("iframe");
$iframes.each(function(index, iframe){
$(iframe).attr("src", $(iframe).attr("src"));
});
});
});
Add this to your layout and you're set.
UPDATE: Code modified for modals with multiple iFrames.

You should empty iframe src first and then set it up again.
So my working answer:
$('#myModal').on('hidden.bs.modal', function () {
var src = $(this).find('iframe').attr('src');
$(this).find('iframe').attr('src', '');
$(this).find('iframe').attr('src', src);
});
October, 2014. For Bootstrap 3.

Here is my solution, it solves the following using bootstrap event calls:
Autoplay movie when showing the modal
Stop movie when modal is hidden
HTML carousel inside modal, first active item is the iframe video
<button class="btn btn-primary" data-toggle="modal" data-target="#myModal">Modal</button>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div id="myCarousel" class="carousel slide carousel-fade" data-ride="carousel">
<div class="carousel-inner" role="listbox">
<div class="item active">
<div class="fill">
<iframe id="videoIframe" width="100%" height="100%" src="https://www.youtube.com/embed/UVAjm8b7YFg?rel=0&showinfo=0" frameborder="0" allowfullscreen></iframe>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Javascript autoplay when displaying modal, then reset the URL and apply it to iframe src again
$('#myModal').on('show.bs.modal', function() {
$("#videoIframe")[0].src += "&autoplay=1";
});
$('#myModal').on('hidden.bs.modal', function(e) {
var rawVideoURL = $("#videoIframe")[0].src;
rawVideoURL = rawVideoURL.replace("&autoplay=1", "");
$("#videoIframe")[0].src = rawVideoURL;
});

This one does it perfectly:
$("#myModal").on("hidden.bs.modal", function(t) {
var o = $(t.target).find("iframe");
o.each(function(t, o) {
$(o).attr("src", $(o).attr("src"))
});
});
If you however want to have it start when modal opens / stop when it closes use this code:
But make sure to add enablejsapi=1 in your src, like this for example:
<iframe src="https://www.youtube.com/embed/YOUR_VIDEO_CODE?rel=0&controls=0&showinfo=0&enablejsapi=1" frameborder="0" allowfullscreen></iframe>
function playStopVideo() {
var youtubeFunc ='';
var outerDiv = $("#myModal");
var youtubeIframe = outerDiv.find("iframe")[0].contentWindow;
outerDiv.on('hidden.bs.modal', function (e) {
youtubeFunc = 'stopVideo';
youtubeIframe.postMessage('{"event":"command","func":"' + youtubeFunc + '","args":""}', '*');
});
outerDiv.on('shown.bs.modal', function (e) {
youtubeFunc = 'playVideo';
youtubeIframe.postMessage('{"event":"command","func":"' + youtubeFunc + '","args":""}', '*');
});
}
playStopVideo();

A much easier way than all of these answers is just replacing the whole src. This works for all modals and you can adjust iframe class as required.
$('.modal').on('hidden.bs.modal', function(e) {
var closestIframe = $(e.currentTarget).find('iframe');
var rawVideoURL = $("iframe")[0].src;
closestIframe[0].src = "";
closestIframe[0].src = rawVideoURL;
});

Reload any iframe in bootstrap modal on hide.bs.modal event.
The setTimeout delay added for fixing iframe rendering after src reset.
$('.modal').on('hidden.bs.modal', function (event){
let iframes = event.target.getElementsByTagName('iframe');
for (let i = 0; i < iframes.length; i++) {
let src_tmp = iframes[i].src;
iframes[i].src = '';
setTimeout(() => {
iframes[i].src = src_tmp;
}, 100);
}
});

I used a combination of Ruslanas Balčiūnas and Nathan McFarland's answers to code something that worked well for me.
$('#myModal').on('hide',function(){
$('.modal-body iframe').attr('src','');
});
So basically this sets the src attribute of the iframe to nothing when the close modal event is triggered. Short and sweet.

My solution to this that works for Bootstrap 3 and the modern YouTube embed format is as follows.
Assuming your video is embedded within a standard Bootstrap 3 Modal with id="#video-modal", this simple bit of Javascript will do the job.
$(document).ready(function(){
$("#video-modal").on('hide.bs.modal', function(evt){
var player = $(evt.target).find('iframe'),
vidSrc = player.prop('src');
player.prop('src', ''); // to force it to pause
player.prop('src', vidSrc);
});
});
I've seen proposed solutions to this issue involving use of the YouTube API, but if your site is not an https site, or your video is embedded using the modern format recommended by YouTube, or if you have the no-cookies option set, then those solutions don't work and you get the "TV set to a dead channel" effect instead of your video.
I've tested the above on every browser I could lay my hands on and it works very reliably.

Expanding on Guille's answer above, this is a drop-in function that will work with Bootstrap 3, the latest version of youtube as of Aug 14, and works for multiple videos /modals in one page.
$(".modal").on('hidden.bs.modal', function(e) {
$iframe = $(this).find( "iframe" );
$iframe.attr("src", $iframe.attr("src"));
});

Had a modal with many videos. Updated the code by #guillesalazar to close multiple videos in the modal.
$("#myModal").on('hidden.bs.modal', function (e) {
$("#myModal iframe").each(function () {
$(this).attr("src", '');
});
});

7 years after, we still need to solve this.
We found a best way to fix it (Inspired by RobCalvert123 answer)
jQuery(".modal-backdrop, .modal.open .close,.modal.open .btn").live("click", function() {
// Get iframe opened
var iframe_open = jQuery('.modal.open');
// Get src from opened iframe
var src = iframe_open.attr('src');
// replace src by src to stop it that's the tips
iframe_open.attr("src", src);
});

1. Embed Youtube on your Page (html)
Add the Youtube div-container to your Website:
<div id="ytplayer">This will be replaced with the Youtube iFrame</div>
Add the Youtube Javascript Api (iFrame)
<script>
// Ads Youtube JS API
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// This function creates an <iframe> (and YouTube player) after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('ytplayer', {
height: '390',
width: '640',
videoId: 'ncif63mSZl4',
WMode: 'transparent',
wmode: 'opaque',
playerVars: {
'autoplay': 0,
'controls': 0,
'autohide':1,
'rel':0,
'showinfo': 0,
'modestbranding': 1,
},
});
}
function stopVideo() {
player.stopVideo();
}
function pauseVideo() {
player.pauseVideo();
}
function playVideo(){
player.playVideo();
}
</script>
Controll with jQuery (Bootstrap Modal)
// Open Modal and start Playing Youtube Video
$("#myModalTrigger").click(function(){
$("#video-modal").modal(); // opens up the Modal
playVideo(); // Starts playing Video
});
// Stop Player on Modal hide
$('#video-modal').on('hide.bs.modal', function (e) {
stopVideo(); // stop player
});

$('#myModal').on('hide', function () {
$('#video_player')[0].stopVideo();
})

#guillesalazaar's answer was only the 1st half of my fix so I felt compelled to share my situation in case it helps someone in the future. I too have an embedded youtube video but I set mine to play automatically when the frame is loaded using autoplay=1. To get around the autoplay issue on page load I have my youtube url stored in a variable that sets the iframe source using a click handler. To solve this I simply removed the attribute source link:
My Url to trigger the modal window:
<div id="movieClick" class="text-center winner">
<a href="#" data-toggle="modal" data-keyboard="true" data-target="#movie">
</div>
My hidden modal window divs:
<div id="movie" class="modal fade" role="dialog" tabindex='-1'>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">They Live (1988)</h4>
</div>
<div class="modal-body">
<iframe id="onscreen" width="100%" height="460px" src="" frameborder="0" allowfullscreen></iframe>
</div>
</div>
</div>
</div>
My JS:
$("#movieClick").click(function(){
var theLink = "https://www.youtube.com/embed/Wp_K8prLfso?autoplay=1&rel=0";
document.getElementById("onscreen").src = theLink;
});
// really annoying to play in the Background...this disables the link
$("#movie").on('hidden.bs.modal', function (e) {
$("#movie iframe").attr("src", '');
});

//stop youtube video on modal close
$('.modal').on('hidden.bs.modal', function () {
var iframVideo = $('.modal').find('iframe');
$(iframVideo).attr("src", $(iframVideo).attr("src"));
});

My solution for 2 or more Youtube videos using the HTML data-* attribute. The video autoplays and stops when the modal is opened and closed.
<button data-url="https://www.youtube.com/embed/C0DPdy98e4c" data-toggle="modal" data-target="#mymodal">Video 1</button>
<button data-url="https://www.youtube.com/embed/ScMzIvxBSi4" data-toggle="modal" data-target="#mymodal">Video 2</button>
<!-- Modal -->
<div id="mymodal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">Close</button>
</div>
<div class="embed-responsive embed-responsive-16by9">
<iframe class="embed-responsive-item" src="" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</div>
</div>
</div>
</div>
$('.modal').on('show.bs.modal', function (event) {
$(this).find('iframe').attr("src", $(event.relatedTarget).data('url') );
});
$('.modal').on('hidden.bs.modal', function (e) {
$(this).find('iframe').attr("src", "");
});
Here is a Codepen demo:
https://codepen.io/danielblazquez/pen/oOxRJq

For angular or for dynamic html or if we have multiple iframes then use as below
$("#myModal").on('hidden.bs.modal', function (e) {
$("#myModal iframe").each(function(){
$(this).attr("src", $(this).attr("src"));
});
});

if you have multiple modals with many videos, let's say you have a modal on each slide on a carousel for instance, you need something more dynamic to close/stop the video in the visible slide and not mess up all the other modals, use this:
$(".modal").on('hidden.bs.modal', function (e) {
$(this).find("iframe").attr("src", $(this).find("iframe").attr("src"));
});

Related

jquery or js to prevent body scroll on ios

I've been unsuccessful in trying out the answers in related questions so any help would be much appreciated.
I have a modal which displays a form in an iframe - this is scrollable. The issue occurs on ios where the body scrolls underneath instead of the iframe. I need to prevent the body from scrolling and allow the iframe to scroll.
The suggested fix from dementic doesn't work properly as the body underneath the modal still scrolls unless you touch scroll the modal in exactly the right place but this is very temperamental.
Modal:
<div class="modal fade" id="myModal">
<div class="modal-dialog">
<div class="modal-content bmd-modalContent">
<div class="modal-body">
<div class="close-button">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="embed-responsive embed-responsive-16by9">
<iframe id="formIframe" class="embed-responsive-item" frameborder="0"></iframe>
</div>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
jQuery/js:
(function($) {
$.fn.bmdIframe = function( options ) {
var self = this;
var settings = $.extend({
classBtn: '.bmd-modalButton',
defaultH: 360
}, options );
$(settings.classBtn).on('click', function(e) {
var allowFullscreen = $(this).attr('data-bmdVideoFullscreen') || false;
var url = window.location.href;
var fieldId = "Form_Source_URL";
var trackingURL = $(this).attr("data-bmdSrc") + '?' + fieldId + '=' + url;
var dataVideo = {
'src': trackingURL,
'height': $(this).attr('data-bmdHeight') || settings.defaultH,
'width': $(this).attr('data-bmdWidth') || settings.defaultW
};
if ( allowFullscreen ) dataVideo.allowfullscreen = "";
$(self).find("iframe").attr(dataVideo);
});
this.on('hidden.bs.modal', function(){
$(this).find('iframe').html("").attr("src", "");
});
return this;
};
})(jQuery);
jQuery(document).ready(function(){
jQuery("#myModal").bmdIframe();
});
//attempted fix to stop body scrolling
var iframe = document.getElementById('formIframe');
iframe.addEventListener('touchmove', function(e) {
e.preventDefault();
}, false);
In project I used this was for Semantic UI modals, and even reused same functionality to help with a custom Coveo modal/popup.
Here is the reusable JQuery function:
// Definite way of removing body scrollbar (mainly for iOS).
forceRemoveBodyScrollbar = function(removeScrollbar) {
bodyScrollPositionBeforeScrollbarRemoved;
if (removeScrollbar) {
bodyScrollPositionBeforeScrollbarRemoved = $(window).scrollTop();
// Add body class that prevents scrolling behind pop up.
$('body').addClass('force-remove-body-scrollbar').css('top', '-' + bodyScrollPositionBeforeScrollbarRemoved + 'px');
} else {
// Remove attributes used to prevent scrolling of content behind Coveo pop up.
$('body').removeClass('force-remove-body-scrollbar').removeAttr('style');
// Scroll back to original top position prior to clicking Filters button.
$(window).scrollTop(bodyScrollPositionBeforeScrollbarRemoved);
}
}
CSS to help with the class that is added/removed:
body.force-remove-body-scrollbar {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: auto;
transition: none;
}
Now, where ever you are executing code to OPEN modal just add forceRemoveBodyScrollbar(true);
Example: if modal opens on click of a button:
$('.myOpenModalButton').on('click', function() {
forceRemoveBodyScrollbar(true);
// Other Modal related JS.
}
And where ever you are executing code to CLOSE modal just add forceRemoveBodyScrollbar(false);
Example: can bind to click event of close button and dark background that appears behind the modal like so:
$('.modalCloseButton, .modalDarkBackground').bind('click', function() {
forceRemoveBodyScrollbar(false);
});

Carousel Slider with YouTube videos

Is it possible to use JQuery to build a youtube video slider? I'd like to display a few ones I uploaded.
Found some answers but made with specific frameworks, if it's possible I'd like to stick with something simple.
I found this code very helpful but I can't seem to make it work.
JSFiddle
$('.play-button').on('click', function () {
$(this).hide();
$(this).parent().fadeOut();
$(this).parent().siblings('.slider-video')[0].play();
});
$('.slider-video').on('play', function () {
$(this).attr('controls', '1');
});
// Additionnal code for the slider
var pos = 0,
slides = $('.slide'),
numOfSlides = slides.length;
function nextSlide(){
stopCurrentVideo();
slides.eq(pos).animate({left:'-100%'},500);
pos = pos >= numOfSlides-1 ? 0 : ++pos;
slides.eq(pos).css({left:'100%'}).animate({left:0},500);
}
function previousSlide(){
stopCurrentVideo();
slides.eq(pos).animate({left:'100%'},500);
pos = pos == 0 ? numOfSlides-1 : --pos;
slides.eq(pos).css({left:'-100%'}).animate({left:0},500);
}
function stopCurrentVideo(){
$('.slider-video:eq('+pos+')').load().removeAttr('controls')
.siblings('.overlay-content').show().find('.play-button').show();
}
$('.left').click(previousSlide);
$('.right').click(nextSlide);
You can achieve this with the YouTube iFrame API:
https://developers.google.com/youtube/iframe_api_reference
This API becomes available when you append enablejsapi=1 to the URLs of YouTube video embeds.
In order to access the controls for stopping videos, for each video you need to access an instance of YT.Player. For each iFrame, I created an instance of YT.Player, and attached it directly to the slide object as a parameter called video.
(Note that many developers say you shouldn't attach data directly to DOM objects, but I did so here because it allowed me to more closely match your original code.)
YT.Player can be accessed through a special function that must be called onYouTubeIframeAPIReady, which I could only get to work if it was outside of $(document).ready.
I can't put my solution on JSFiddle because the iFrames don't play nice, so here's my implementation on GitHub:
http://robertakarobin.github.io/jquery-video-slider
https://github.com/robertakarobin/jquery-video-slider
Here are the relevant bits:
HTML:
<div class="video-slider">
<!-- SLIDE 1 -->
<div class="slide">
<iframe class="video" src="https://www.youtube.com/embed/YE7VzlLtp-4?ecver=2&enablejsapi=1"></iframe>
</div>
<!-- SLIDE 2 -->
<div class="slide">
<iframe class="video" src="https://www.youtube.com/embed/YE7VzlLtp-4?ecver=2&enablejsapi=1"></iframe>
</div>
<!-- END OF SLIDES -->
<div class="slide-arrow left"></div>
<div class="slide-arrow right"></div>
</div>
JavaScript:
$(document).ready(function () {
var pos = 0,
slides = $('.slide'),
numOfSlides = slides.length;
function nextSlide() {
// `[]` returns a vanilla DOM object from a jQuery object/collection
slides[pos].video.stopVideo()
slides.eq(pos).animate({ left: '-100%' }, 500);
pos = (pos >= numOfSlides - 1 ? 0 : ++pos);
slides.eq(pos).css({ left: '100%' }).animate({ left: 0 }, 500);
}
function previousSlide() {
slides[pos].video.stopVideo()
slides.eq(pos).animate({ left: '100%' }, 500);
pos = (pos == 0 ? numOfSlides - 1 : --pos);
slides.eq(pos).css({ left: '-100%' }).animate({ left: 0 }, 500);
}
$('.left').click(previousSlide);
$('.right').click(nextSlide);
})
function onYouTubeIframeAPIReady() {
$('.slide').each(function (index, slide) {
// Get the `.video` element inside each `.slide`
var iframe = $(slide).find('.video')[0]
// Create a new YT.Player from the iFrame, and store it on the `.slide` DOM object
slide.video = new YT.Player(iframe)
})
}
The slider seems to be working fine. Just change the code from Video tag to YouTube Embed Code and you have a Youtube player Carousel.
<div class="video-slider">
<!-- SLIDE 1 -->
<div class="slide">
<div style="position:relative;height:0;padding-bottom:56.28%"><iframe src="https://www.youtube.com/embed/YE7VzlLtp-4?ecver=2" style="position:absolute;width:100%;height:100%;left:0" width="640" height="360" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></div>
</div>
<!-- SLIDE 2 -->
<div class="slide">
<div style="position:relative;height:0;padding-bottom:56.28%"><iframe src="https://www.youtube.com/embed/EngW7tLk6R8?ecver=2" style="position:absolute;width:100%;height:100%;left:0" width="640" height="360" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></div>
</div>
<!-- END OF SLIDES -->
<div class="slide-arrow left"></div>
<div class="slide-arrow right"></div>
</div>
You can get the YouTube Embed Code by right clicking on the video on youtube.com and select Copy Embed Code, and use that code in the slider.
Hope it helps.
I have made a fork of the author fiddle and made the changes. JSFiddle

Stop slider when embedded movie plays.

I have a Slider that I have modifed the code so it stops on mouseover. So far so good. but.. As you can see in the html I have one slider with en embedded video.
My problem is that even though the slider now stops on hover, I also want it to stop when I play an embedded video. Preferably, but not necessary, resume the slider when the video ends.
Javascript:
var VSliderHome = true;
$("#SliderHome").hover(function() {
VSliderHome = false;
}, function() {
VSliderHome = true;
});
function autoplaySlider(length) {
if (VSliderHome) {
if (visibleSlidePosition < length - 1) {
nextSlide(slidesWrapper.find('.selected'), slidesWrapper, sliderNav, visibleSlidePosition + 1);
visibleSlidePosition += 1;
} else {
prevSlide(slidesWrapper.find('.selected'), slidesWrapper, sliderNav, 0);
visibleSlidePosition = 0;
}
updateNavigationMarker(navigationMarker, visibleSlidePosition + 1);
updateSliderNavigation(sliderNav, visibleSlidePosition);
}
}
HTML:
<slider.body>
<section class="cd-hero">
<ul id="SliderHome" class="cd-hero-slider autoplay">
<li class="selected">
<div class="cd-full-width" style="background-image: url(img/fileupload/zlide.jpg)">
<div class="textcont-left">
<h2>text</h2>
<p>text</p>
Köp Nu
</div>
</div>
</li>
<li style="background-image: url(img/fileupload/smatrphones.jpg)">
<div class="cd-half-width cd-img-container">
<iframe width="560" height="315" src="https://www.youtube.com/embed/fXu2fWz" frameborder="0" allowfullscreen></iframe>
</div>
<div class="cd-half-width">
<div class="textcont-right">
<h2>text</h2>
<p>text</p>
Mer Information
</div>
</div>
</li>
</section>
</body>
Add an on-click function in the current function of the slider... Similar to the on-hover,however do it on-click, so that when you click in the area of the PLAY it will effect the slider... even though you're clicking play and the click has nothing to do with the slider, the fact that the video is on the slider and the slider is awaiting an on-click function result... works.
Use the video event play/pause to change your variable
$('video').on('play pause', function(e){
VSliderHome = e.type === 'pause';
})
You need to listen for events from the video and respond accordingly. You can see the details of how to do this in the YouTube Player API Reference.
As a quick example, you might want something like this:
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
// stop slider
} else if (done) {
// start slider
}
}

Twitter Bootstrap Modal Event Not Fired When Modal is Shown

According to the docs:
http://getbootstrap.com/javascript/#modals
It should fire the methods "show.bs.dropdown" and "shown.bs.dropdown". But it doesn't:
http://jsfiddle.net/mQunq/3/
HTML:
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">Hello world</div>
</div>
</div>
jQuery:
// show.bs.modal doesn't work either
$('#myModal')
.modal('show')
.on('show.bs.modal', function() {
alert('shown baby!');
});
Youe need first register event then trigger it
$('#myModal')
.on('show.bs.modal', function() {
alert('shown baby!');
}).modal('show');
jsfiddle
When it happens
Event shown.bs.modal is not fired when modal has also class "fade". Whereas show.bs.modal always works.
See https://github.com/twbs/bootstrap/issues/11793
HTML:
<div class="modal fade" id="first" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">Hello world from first modal</div>
</div>
</div>
<div class="modal" id="second" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">Hello world from second modal</div>
</div>
</div>
jQuery:
$('.modal').on('shown.bs.modal', function() {
//fired only in second modal
console.info('shown.bs.modal');
});
$('.modal').on('show.bs.modal', function() {
//fired always
console.info('show.bs.modal');
});
Solution
For bootstrap v3.3.6 replace line 1010 with:
that.$element // wait for modal to slide in
What is the problem
Look at lines 1006-1015:
var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
transition ?
that.$dialog // wait for modal to slide in
.one('bsTransitionEnd', function () {
that.$element.trigger('focus').trigger(e)
})
.emulateTransitionEnd(Modal.TRANSITION_DURATION) :
that.$element.trigger('focus').trigger(e)
Without transition (no fade class) the event e is triggered right away (on that.$element).
With transition, I'm not sure why exactly, but somehow the bsTransationEnd event from function emulateTransitionEnd is not handled by that.$dialog.one(). But with that.$element, everything seem to work.
Similar thing happened to me and I have solved using setTimeout.
Bootstrap is using the following timeout to complete showing:
c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,
So using more than 300 must work and for me 200 is working:
$('#myModal').on('show.bs.modal', function (e) {
setTimeout(function(){
//Do something if necessary
}, 300);
})
you forgot the "n" on shown
$(document).ready(function(){
$('#myModal')
.modal('show')
.on('shown.bs.modal', function() {
alert('shown baby!');
});
});
Use document instead of your custom selector. Both shown.bs.modal and show.bs.modal work just fine
$(document).on('shown.bs.modal', '.modal', function() {
alert();
});
In case someone stumbles upon this problem, make sure you hook the on hidden / shown event before firing the toggle of the modal. That is, declare this:
$("#selector").on("hidden.bs.modal", function () {
// do the right thing
});
Before calling the toggle of the modal, e.g.:
("#selector").modal("toggle");
I know this is basic, but in a convoluted code it happens.
I found a solution that works with .fade transitions:
$(document).on($.support.transition.end, '.modal.fade.in', function(e) {
var $target = $(e.target);
if ($(e.target).is(".modal-dialog")) {
console.log("Modal Shown")
}
});
$(document).on($.support.transition.end, '.modal.fade', function(e) {
var $target = $(e.target);
if (!$target.is(".modal.fade.in") && !$target.is(".modal-dialog")) {
console.log("Modal Hidden")
}
});
If your modal is dynamically created, select the closest static parent element and add your modal as a parameter for bootstrap modal events to work:
/* body is static, .modal is not */
$("body").on('shown.bs.modal', '.modal', function() {
alert('shown');
});
$("body").on('hidden.bs.modal', '.modal', function() {
alert('hidden');
});
$("body").on('show.bs.modal', '.modal', function() {
alert('show');
});
$("body").on('hide.bs.modal', '.modal', function() {
alert('hide');
});

I can't get Youtube API To Work

I want the player to stop when the the div (.closed) is clicked but it' not woroking. Can someone see where I've gone wrong?
Ive added in the head
<script type="text/javascript" src="http://www.youtube.com/player_api"></script>
I've got this in my jQuery
closed.click(function () {
player.stopVideo();
movie.delay(1000).animate({
bottom: -500
}, {
duration: 1000
});
});
** This also messes with the animation*
and this in my code.
<div id="movieContainer">
<div id="movie">
<iframe id="player" width="644" height="410" src="http://www.youtube.com/embed/VG9AGf66tXM?rel=0&wmode=Opaque&enablejsapi=1" frameborder="0" allowfullscreen></iframe>
<div class="close"></div>
</div><!--End of Movie -->
</div><!-- End of movieContainer -->
how do you get the reference to player? It should be something like this:
var player = document.getElementById("player");
player.stopVideo();

Categories