How to make a sound only play once - javascript

How do I make it play the sound only once I tap the spacebar and not when I'm holding it down and when I'm holding it down I want it to only play it once.
// makes my character jump
if (keys.jump && is_grounded) {
yvel = jump;
// plays a cat sound when I jump problem
cat.play();
}

Your event listener should be on keydown event to play the audio.
And then on another event listener keyup event, you can remove the audio element.
I can't help you more specifically without you posting your code. Hope that helps!

Related

JavaScript function logic to play/pause HTML5 video

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.

Delegated event triggering even when it shouldn't

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...

GetElementby More Item

I use the VideoJS framework, i want know when the user pause the video. The video go to pause when i click on "Play button" and on video:
var vjs = document.getElementById("really-cool-video_html5_api"); // on video
var vjs = document.getElementById("really-cool-video").getElementsByClassName("vjs-play-control")[0]; // click button play
I with Listener, see if the user click on this "div" :
vjs.addEventListener("click", checkPause, false);
but it control only when i click on document.getElementById("really-cool-video").getElementsByClassName("vjs-play-control")[0] i want, both 2 div in my listener... I can't change the HTML and tell the div with the same name... How i can do a Listener of two elements?
You're probably better off using video.js's api to listen for pause events instead. There are ways to pause the video without clicking (keyboard control) and clicks that do not pause the video (play).
videojs('really-cool-video').on('pause', checkPause)
You have the same named variables your attaching listeners to. Try changing the second vjs to vjsBtn like so...
var vjsInnerBtn = document.getElementById("really-cool-video_html5_api"); // on video
var vjsPlayerBtn = document.getElementById("really-cool-video").getElementsByClassName("vjs-play-control")[0]; // click button play
Now you are free to accomplish this.
vjsInnerBtn.addEventListener("click", checkPause, false);
vjsPlayerBtn.addEventListener("click", checkPause, false);
I'm assuming jQuery is available to you, since you've tagged it. This makes things much easier for you, because you simply have to fill the selector with the elements you want the event handler attached to:
$('#really-cool-video_html5_api, #really-cool-video .vjs-play-control').on('click', checkPause);
Note, this still adds multiple event handlers, this must be done if you want the same functionality triggered from a click on two different elements.
have you considers store them in an array? like
var controls['video'] = document.getElementById("really-cool-video_html5_api"); // on video
controls['pause_btn'] = document.getElementById("really-cool-video").getElementsByClassName("vjs-play-control")[0];
//Here you add the addEvenListener with the array elements.
is the same approach to using different variables but you can iterate them if you want to attach them same event listener or use a function for that

Close popup with key Esc

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.

window tab pressed event

I want my html5 canvas game to automatically pause when the user opens up another tab inside the browser. What is the name of the event that is fired when a user does this?
$(window).blur( function() {
});
or in js:
window.onblur = function() {
}
There is no "new tab opened" event. But pausing on the blur event will do what you want - whenever the window loses focus the game will pause. You can then resume game in the focus event.
As an alternative to the blur event suggested in another answer, you could use the new window.hidden property of HTML5.
Good places to read up on this are:
https://developer.mozilla.org/en-US/docs/DOM/Using_the_Page_Visibility_API
http://www.html5rocks.com/en/tutorials/pagevisibility/intro/
The biggest problem using this specification today is that you'll have to cater for vendor prefixes to handle it in all browsers. But if you ignore that it really comes down to:
if (!window.hidden) {
// do whatever you normally do to render a frame
}
There are corresponding visibilitychange events in case you'd prefer to keep the detection out of your game loop.

Categories

Resources