I have a script which plays/pauses a HTML5 video based on the window size. When the user enters fullscreen, the video plays. When the user exits fullscreen, the video pauses, as expected. If you enter fullscreen again on the paused video, it will call a play and then pause immediately.
Here's the play/pause script and the console logs:
// Listen for exiting fullscreen, hide video element.
$("#" + m).on("webkitfullscreenchange", function(e) {
this.className = "hide";
if($("#" + m).get(0).paused) {
v.play();
console.log('playing...')
} else {
v.pause();
console.log('pausing...')
}
Here's a CodePen demo with representative HTML and the full script.
What can I do in my logic to prevent the second pause call being made?
I found the origin of your problem.
Here is the general structure of your code :
$(document).ready(function() {
$('.cell').on('click', function() {
// some more code ...
$("#" + m).on("webkitfullscreenchange", function(e) {
// here the code for the event handler that pauses and plays the video
});
)};
)};
You can see that the code that adds the handler on the "webkitfullscreenchange" event... is inside the handler for the .cell click event !
Here what happens : every time you click on the cell, you request the fullscreen, and you add a new event handler on the "webkitfullscreenchange" event (in jQuery, on register a new event handler, it does not replace the previous one if there was one).
The first time you click, you add the handler and you request full screen mode : it emits the event, your single handler gets it and plays the video.
But the second time you click, you request full screen mode and you add a second handler. When the event is emitted, both handlers react : the first one plays the video, and the second... immediately pauses it.
So here's part of the solution : just remove the part where you register more event handlers out of the click event handler (as a rule of thumb, situations when you have to set up handlers inside other handlers are very specific, so do not do it if you don't have any specific reason).
Why part ? Because even if it solves your first problem, it does leave another one: what happens if you click, let the video finish, and then quit full screen mode? The handler will get called, verify if the video is playing, notice that it is not and start playing it... even if you just left full screen.
So here's the final solution: set up your handler so that it checks if you just went in or out of full screen mode(using document.webkitIsFullScreen), and play or pause accordingly, as per #CBroe suggestion in the comments.
$('video').on('webkitfullscreenchange', function(e) {
if(document.webkitIsFullScreen) {
this.play();
} else {
this.className = "hide";
this.pause();
}
});
I forked your CodePen and set up the full solution if you want to have a look.
Related
I was trying to make a webapp with html elements that will move form div to antoher div when clicked but also I want to be able fire event when users hold that element for more than a second. So I have this code
$(document).on("click",'.card', function() {
var card=$(this).parent();
if(card.parent().attr('id')==="options"){
card.appendTo("#choice");
}
else{
card.appendTo("#options");
}
});
var timeoutId = 0;
$('.card').on('pointerdown', function() {
timeoutId = setTimeout(showModal, 1000);
}).on('pointerup mouseleave', function() {
clearTimeout(timeoutId);
});
And it is doing almost fine. The problem occures when the element is clicked. It is appended to different div as it should but the mobile pointer is still on it so when I try to fire 'hold' event on another element it is not working for the first time since 'pointerup' event from previous element is firing right after 'pointerdown' event (So you need to try to hold next element twice).
I've dealt with it by adding a simple boolean flag in click event function so it is blocking next first call of 'pointerup' event but this is a very ugly solution.
Do you have any ideas how can i improve this? Maybe there is a way to call 'pointerup' event manually after click?
Removing 'mouseleave' event and adding 'pointerleave' instead fixed the problem.
Not really sure how 'mouseleave' event was fired on mobile device though.
The HTML 5 audio API is super easy, this page tells it all. But I am failing to achieve the following: catch the error (if there was one) and do something else when there are NO errors!
You may think this is easy, and that I should attach event listeners to the "error" and "play" events. But know the following:
The "error" event works only on the sub element "source", not the "audio" tag itself, this of course makes sense, since there could be more than one source.
The "play" event triggers when the file starts playing for the first time and also when the file is paused and played again!
The "play" event is triggered regardless of any errors!
What I am trying to do is simply set both the "error" / "play" events, but prevent the "play" whenever an error occurs.
var player = $('audio#player');
player.find('source').on('error', function(){
alert('Cannot play this file!');
});
player.on('play', function(){
setTheNextSongToPlay(' .... ');
});
Now, the "setTheNextSongToPlay" function is called whether there were any errors or not. How is that possible anyway ?! THE FILES WASN'T PLAYED!
I have the following code:
// Define controls
$('.play-video').click(function(){
// Get the video element
var video = $(this).parent().parent().find('video');
// Play the video
$(video).get(0).play()
// Remove the play class and add the pause class so the same button will pause the video
$(this).removeClass('play-video');
$(this).addClass('pause-video');
// Set pause text
$(this).text('Pause');
});
$(document).on('click','.pause-video',function(){
console.log('pausing...');
// Get the video element
var video = $(this).parent().parent().find('video');
// Play the video
$(video).get(0).pause()
// Remove the play class and add the pause class so the same button will pause the video
$(this).removeClass('pause-video');
$(this).addClass('play-video');
// Set pause text
$(this).text('Play');
});
Problem is, that the second click event should trigger on .pause-video only but also triggers on .play-video
Question is: What did I do wrong?
Thanks in advance,
G3
You've attached the "play" event handler directly to the button instead of using delegation. That handler will continue to fire because of that, even if you change the class.
Delegation works through event bubbling, and the selector you pass in to the .on() call is re-examined with every event. That is not the case with handlers that are directly attached: once those are active, they're active until they're removed or until the DOM element itself is removed. Changing the particulars of the DOM element won't make a difference.
Your problem can therefore be solved by using delegation for both cases.
Your code is close. but your first event handler also needs to be delegated too:
$(document).on('click', '.play-video', click(function(){
try to stop immediage propagation $('.play-video').click
The problem is that jQuery can't track object changes on the fly. Just use one click event, and determine what to do inside this:
$('.play-stop-video').click(function(){
if($(this).hasClass('play')) {
// Current play button code here....
}
if($(this).hasClass('stop')) {
// Current stop button code here....
}
$(this).toggleClass('play').toggleClass('stop');
});
$(something).click( ... will runs when the page loads, and attach the click events to the play and stop buttons. However, you don't have any stop buttons at this time, so the click event for this will be discarded...
I try to close popup when I press Esc but it only works while video isn't on play.
$(document).bind('keydown', function (e) {
if(e.which === 27){
$('#youmax-video-lightbox').attr('src', '');
$('#youmax-lightbox').hide();
}
});
U can see in:
http://www.vigerm.com/videos
I think this is because when the user clicks on play to start the video, the flash object gets the focus and the document does not receive anymore the input events.
Not sure what you can do about it. Maybe auto-play the videos when opening the pop-up?
It has nothing to do with whether or not the video is playing. If you open the video without clicking anything else, Esc still closes it fine. It's when you click the video, events no longer bubble up to the document, so your handler is never called. You need to either stop the video from stopping event propagation or attach handlers to the video element itself as well.
I have an element that contains a video player: that video player can either be Flash or HTML5 based. I want to be able to make that element fullscreen (I know, only works in webkit at the moment) and run some resizing scripts when it happens.
Here is how I do it:
this.getEl('.fullscreen').bind('click', $.proxy(function() {
this.getEl('#tpPlayer')[0].webkitRequestFullScreen();
}, this));
And the event listener:
this.getEl('#tpPlayer').bind('webkitfullscreenchange', function() {
console.log('fullscreen change');
$(this).toggleClass('tpPlayer tpPlayerFullScreen');
});
When #tpPlayer contains a <video> element, everything works fine: the element goes fullscreen, the event fires, the message is logged and the classes are toggled. However, when #tpPlayer contains a Flash <object>, the element goes fullscreen fine, but no event is fired (so the callback does not run either).
Why is this happening and how to avoid this?