What is the way to disable or prevent events from the play/pause button in the html5 audio element?
I am trying something like this:
document.getElementById(id).addEventListener("pause", function() {
$(this).trigger("play");
});
This works when alone, but my problem is that I would like to control the play/pause when clicking on the div where the audio element is in:
<div id="my_div">
<audio controls id="my_audio">
<source src="my_song.mp3" type="audio/mpeg">
</audio>
</div>
var is_playing;
$("#my_div").click(function () {
if (is_playing) {
$('#my_audio').trigger("pause");
is_playing = false;
} else {
$('#my_audio').trigger("play");
is_playing = true;
}
});
so this causes conflict when I use the pause/play buttons of the audio element. So, I am searching a way to prevent the event of the play/pause audio element control (but not the whole controls as I need to use the seekbar and volume).
play and pause are not jQuery methods. Try calling .play(), .pause() on <audio> element
$(function() {
var is_playing;
$("#my_div").click(function(e) {
// if `e.target` is not `<audio>` element
if(e.target.tagName !== "AUDIO") {
if (is_playing) {
$('#my_audio')[0].pause();
is_playing = false;
} else {
$('#my_audio')[0].play();
is_playing = true;
}
} else {
e.stopPropagtion()
}
});
});
plnkr http://plnkr.co/edit/l5NejZ4rvxTZLPghkFWF?p=preview
Related
I have a element where I would like to toggle the default controls when clicking the element, but when the controls are shown using these controls shouldn't toggle control visibility.
I'm adding the handler as bubbling, hoping that the built-in controls would preventDefault such that my handler was never invoked but the event caller is always called at least on Safari.
var video = document.getElementById("video");
video.addEventListener('click', function(evt) {
video.controls = !video.controls
});
Is there some other way to add the event handler or perhaps properties on the event I can use to differentiate clicks on the video controls vs. clicks other places in the video element?
"Is there some other way to add the event handler or perhaps properties on the event I can use to differentiate clicks on the video controls vs. clicks other places in the video element?"
No Apple devices here to test on Safari but, in Chrome the clicking of a UI button (like "Play" or "Fullscreen") does not count as a click on the <video> element itself.
You can differentiate by knowing that if the element (picture part, not buttons) is clicked then it returns as: [object HTMLVideoElement]
In your code you can test as:
vid.addEventListener('click', function(evt) {
alert("click target is : " + evt.target);
vid.controls = !vid.controls
});
As a quick side-note, you can see how there is also an opportunity to create one "master" click function, like document.addEventListener('click' ... where you check the evt.target or even the evt.target.id and use If/Else to control anything clicked on the page from just one function. Example:
if (evt.target.id == "myVid") { ...do_someThing(); }
Finally, see if the code below is doing what you want to actually achieve...
You can preview the code at this W3Schools page :
<html>
<body>
<h1>Video UI : click test</h1>
<video id="myVid" width="320" height="240" loop controls>
<source src="movie.mp4" type="video/mp4">
</video>
<script>
var isPlaying = false;
var vid = document.getElementById("myVid");
vid.addEventListener("click", onclick );
function onclick(evt)
{
evt.preventDefault();
if ( vid.paused == true) { isPlaying = false; }
else{ isPlaying = true; }
if( evt.target.nodeName == "VIDEO") { vid.controls = !vid.controls; }
if ( isPlaying == true) { vid.play(); }
}
</script>
</body>
</html>
I'm using flickity, which is a bit irrelevant, and on first load and for each 'change' of a slide I'll search the slide for any videos that have audio enabled (set as a data attribute via PHP via CMS) and then it'll autoplay the video and if the user clicks an unmute button then it'll unmute and vice versa.
This worked fine going forward but going back once the mute button is clicked, the eventListener for the click will fire every time it's existed. I'm guessing the eventListener is being added to each time but I can't work out how to remove the eventListener.
Any help on how to prevent the muteButton.addEventListener('click') from being fired more than once?
//
playVideo = function(index) {
var videos, video, muteButton = null, hasAudio = false;
// Pause all other slide video content if it was playing
flkty.cells.forEach(function(cell, i) {
videos = cell.element.querySelectorAll('video.--autoplay');
videos.forEach(function(video) {
if (video !== null && typeof video !== 'undefined') {
if (!video.paused) {
video.pause();
}
}
});
});
// For current slide
if (index == flkty.selectedIndex) {
videos = flkty.selectedElement.querySelectorAll('video.--autoplay');
muteButton = flkty.selectedElement.querySelector('a.button__mute');
// If videos exist on the current slide
if (videos.length) {
videos.forEach(function(video, index) {
if (video !== null && typeof video !== 'undefined') {
video.play();
if (muteButton !== null && typeof muteButton !== 'undefined' && index == 0) { // Only fire this once per video (as mute = mute all)
console.log(muteButton);
muteButton.addEventListener('click', function(e) {
e.preventDefault();
console.log('clicked'); // TOFIX; fires multiple times
muteVideo(videos, video, muteButton, true);
});
}
}
return;
});
}
}
};
flkty.on('select', function(event, index) {
if (index === 0) {
playVideo(index);
return false;
}
});
flkty.on('change', function(index) {
playVideo(index);
});
//
muteVideo = function(videos, video, muteButton, hasAudio) {
console.log('hasAudio');
if (videos.length > 1) {
videos.forEach(function(video, index) {
if (video.muted == true) {
video.muted = false;
if (index == 0) {
$(muteButton).text('mute');
}
} else {
video.muted = true;
if (index == 0) {
$(muteButton).text('unmute');
}
}
});
} else {
if (video.muted == true) {
$(muteButton).text('mute');
video.muted = false;
} else {
$(muteButton).text('unmute');
video.muted = true;
}
}
};
Just use removeEventListener().
To remove event handlers, the function specified with the addEventListener() method must be an external function.
Anonymous functions, like yours, will not work.
As for only attaching it once: Just set a flag to be checked before adding the eventhandler in the first place.
Don't use removeEventListener() in this case. The real problem is that you are adding event listeners each time your playVideo() function is called. So the problem you should solve is to make sure you only add the event listeners once, probably when the page initializes or something.
Here is what I would do:
Extract the "add event listener code" into a separate function, addButtonListeners() by removing that piece of code from the playVideo(). Then call the addButtonListeners() once when your page is loaded.
I have the below click function so that when a video is clicked the video plays. It works perfectly on desktop browsers, but on tablets does not. You press it and the video instantly pauses. I believe this is to do with the click function looking for a click and there not being one on a tablet but I'm unsure how to solve it.
HTML
<div class="section">
<div class="video">
<video poster="img/my-poster.jpg"><source src="mp4/low-res/my-video.mp4" type="video/mp4"></video>
</div>
</div>
jQuery
$(document).ready(function () {
$('.section video').on("click touchstart", function() {
this.paused ? this.play() : this.pause();
});
});
That's because your touchstart and click are in conflict.
There is a hack to prevent this conflict :
var flag = false;
$('.section video').on("click touchstart", function(){
if (!flag) {
flag = true;
setTimeout(function(){ flag = false; }, 100);
this.paused ? this.play() : this.pause();
}
return false;
});
Credits and more informations : How to bind 'touchstart' and 'click' events but not respond to both?
EDIT : Thanks #RoryMcCrossan for precisions about bind()
I have the following modal box:
<div class="modal-video" id="v-5417">
<div class="video-player">
<video id="v-5417-tape" preload="none">
<source type="video/mp4" src="videos/anthem-od47.mp4">
<source type="video/webm" src="videos/anthem-od47.webm">
</video>
<div class="close-modal fade-control"></div>
</div>
</div>
and trying to use the following e.keyCode to close the modal:
$(document).keydown(function (e) {
if (e.keyCode == 27) {
$(".modal-video").hide();
}
});
This is only hiding the video, but not closing the modal and killing the video. How can I completely close the modal and video together?
jQuery .hide() just changes the CSS style to display:none, so your video is hided and still playing in the background. To fix that issue, you can stop playing the video by standard HTML5 pause() method.
If hiding $(".modal-video") doesn't work for you, then I assume you need to hide it's parent - but we have to see more your code to be sure about that.
$(document).keydown(function (e) {
if (e.keyCode == 27) {
var video = document.getElementById("v-5417-tape");
video.pause()
$(".modal-video").parent().hide();
}
});
If you are using some kind of player template or plugin, and click on class "close-modal" hides the modal as you expect - then you can use jQuery .toggle() method to call click event on that element, when you press your key.
$(document).keydown(function (e) {
if (e.keyCode == 27) {
var video = document.getElementById("v-5417-tape");
video.pause()
$(".close-modal").toggle("click")
}
});
The active state has to be removed, and that disabled the popup.
$(document).keydown(function (e) {
var video = document.getElementById("v-5417-tape");
if (e.keyCode == 27) {
if(video.play){
video.pause();
}
$(".modal-video").removeClass("active");
}
});
I'm working on an HTML5 video logging and transcription application. The transcriptionist needs to be able to start and stop the video using a keyboard shortcut / accelerator rather than clicking a button. Is there a way for me to use javascript to do this without leaving the textarea box?
Thanks,
Norm
Try this JSFiddle. Shortcut for stopping/starting the video is 'alt + enter key'.
HTML:
<video src="http://v2v.cc/~j/theora_testsuite/320x240.ogg" controls id="video">
Your browser does not support the <code>video</code> element.
</video>
<textarea></textarea>
Javascript (using jQuery):
$(function(e) {
$('textarea').keydown(function(e) {
// shortcut for stopping/starting the video
// is alt + enter
if (e.altKey && e.keyCode == 13) {
toggleVideoPlay();
return false;
}
});
});
function toggleVideoPlay() {
var video = $('#video')[0];
if (video.paused) {
video.play();
} else {
video.pause()
}
}