Audio on add to cart with raw javascript - javascript

What exactly is wrong with my selection?
<audio id="cart_add_sound" controls="" preload="auto" hidden="hidden"> <source src="img/cart_add.wav"
type="audio/wav"> </audio>
creating a function
targeting class button-4
attaching an even listener to mouse click
and play the audio with an id of cart_add_sound
// Play Audio on Add to Cart
function playAudio() {
var play = document.querySelector('.button-4')
play.addEventListener('click', function() {
document.getElementById('cart_add_sound').play();
}, true);
}
i know i could use inside html5 onclick="audio.play()" but i want to approach it this way for learning purpose.

You should initialize / execute this function, for example, after the DOM is ready:
// Play Audio on Add to Cart
function playAudio() {
var play = document.querySelector('.button-4')
play.addEventListener('click', function() {
document.getElementById('cart_add_sound').play();
}, true);
}
// DOM ready event
document.addEventListener('DOMContentLoaded', (event) => {
playAudio();
});
Have you run it somewhere?
Demo - https://codepen.io/vyspiansky/pen/BaKKdvW

i fixed it by using getElementsByClassName
and looping through all elements.
// Play Audio on Add to Cart
function playAudio() {
var plays = document.getElementsByClassName('button-4')
for (var i = 0; i < plays.length; i++) {
var play = plays[i]
play.addEventListener('click', function() {
document.getElementById('cart_add_sound').play();
}, true);
}
}

Related

How do I get video to play and pause with a mouse over and blur set with getElementsByTagName

I am working on my portfolio site to make it more ADA compliant when I noticed a lot of redundant code that I want to optimize. I have seven videos on the screen and each have a onmouseover and onmouseout event attributes. I wanted to create a JavaScript that just assigned these event handlers to all video tags on the screen in one function run on startup.
This worked using html code
<video class="nlm-marque-video" id="aerialVideo">
<source src="videos/aerial-view-of-san-diego.mp4"
onmouseover = "playVid(this);"
onmouseout ="pauseVid(this);"
type="video/mp4">
</video>
<script>
/*
* get reference of all video tags on page
* set the video attributes to same defaults
* start videos automatically the first time with muted
*/
function videoEnhance(){
let vid = document.getElementsByTagName("video");
for (i=0;i<vid.length; i++) {
vid[i].autoplay = true;
vid[i].muted = true;
vid[i].controls = true;
vid[i].addEventListener("onmouseover", playVid(this));
vid[i].addEventListener("onmouseout", pauseVid(this));
}
}
/*
* function to play video event
*/
function playVid(vidObj) {
vidObj.play();
console.log("video is playing");
}
/*
* function to pause video on event
*/
function pauseVid(vidObj) {
vidObj.pause();
console.log("video is paused");
}
</script>
index.php:346 Uncaught TypeError: vidObj.play is not a function
at playVid (index.php:346)
at videoEnhance (index.php:338)
at onload (index.php:24)
playVid # index.php:346
videoEnhance # index.php:338
onload # index.php:24
The videos runs, but do not respond to the mouseover and mouseout events.
I think that your simplest solution would probably be to just use the event to play and pause things.
function videoEnhance(){
let vid = document.getElementsByTagName("video");
for (i=0;i<vid.length; i++) {
vid[i].autoplay = true;
vid[i].muted = true;
vid[i].controls = true;
vid[i].addEventListener("mouseover", playVid); //Don't pass in param here.
vid[i].addEventListener("mouseout", pauseVid); //Or here
}
function playVid(e) {
e.target.play(); //use the event
console.log("video is playing");
}
function pauseVid(e) {
e.target.pause(); //use the event
console.log("video is paused");
}
}

Play sound on link click then redirect

I have the following JS:
var links = document.getElementsByClassName('swoosh'),
audio = document.getElementById('a-on-click'),
clickHandler = function () {
audio.play();
}
;
for (var i in links) {
links[i].addEventListener('click', clickHandler);
}
For the following HTML:
Link 1
Link 2
Link 3
<audio id="a-on-click">
<source src="https://sporedev.ro/pleiade/sounds/swoosh-enter.mp3" type="audio/mpeg">
</audio>
The script works like a charm, only activating the sound if the a has class="swoosh". However, the problem appears when the link in the href is an actual link and not a #.
I did some research on SO and Google. I thought that preventDefault() would be the solution here, however I'm starting to doubt that because what I want is for the sound file to play and then redirect to the location specified in the href, not to stop the link functionality entirely. The solution should also only apply to links that have the "swoosh" class.
How is this achievable?
You can find a JSFiddle to play with here.
Rahul's got it; then, wait til the audio finishes and then navigate.
var links = document.getElementsByClassName('swoosh'),
audio = document.getElementById('a-on-click'),
clickHandler = function(event) {
event.preventDefault();
audio.addEventListener('ended', function(){
window.location.href = event.target.href;
})
audio.play();
};
for (var i in links) {
links[i].addEventListener('click', clickHandler);
}
Link 1
Link 2
Link 3
<audio id="a-on-click">
<source src="https://sporedev.ro/pleiade/sounds/swoosh-enter.mp3" type="audio/mpeg">
</audio>
To prevent immediate click effect use one of these inside your listener.
event.preventDefault() || event.stopPropagation();
When you are done playing sound add an event listener for when the sound ends to change the location of the current window.
window.location = event.target.href;
var links = document.getElementsByClassName('swoosh'),
audio = document.getElementById('a-on-click'),
clickHandler = function(event) {
event.preventDefault();
event.stopPropagation();
audio.play();
audio.addEventListener('ended', function(){
window.location = event.target.href;
})
};
for (var i=0; i < links.length; i++) {
links[i].addEventListener('click', clickHandler, true, true);
}
Link 1
Link 2
Link 3
<audio id="a-on-click">
<source src="https://sporedev.ro/pleiade/sounds/swoosh-enter.mp3" type="audio/mpeg">
</audio>
Use event.preventDefault() in the clickHandler, it will block the default behavior of the links with that particular class:
var links = document.getElementsByClassName('swoosh'),
audio = document.getElementById('a-on-click'),
clickHandler = function(event) {
event.preventDefault();
audio.addEventListener('ended', function() {
window.location = event.target.href;
});
audio.play();
};
for (var i in links) {
typeof i === 'Number' && links[i].addEventListener('click', clickHandler);
}
Link 1
Link 2
Link 3
<audio id="a-on-click">
<source src="https://sporedev.ro/pleiade/sounds/swoosh-enter.mp3" type="audio/mpeg">
</audio>
Docs: Event.preventDefault() - Web APIs | MDN
EDIT 1: Please use the audio.addEventListener from Ben's answer. He's got it.
EDIT 2: Changed code in for to check if i is Number type
EDIT 3: Your href is incorrect. Use the one below:
clickHandler = function(event) {
var href = this.href; // cache href here
event.preventDefault();
event.stopPropagation();
audio.play();
audio.addEventListener('ended', function(){
window.location = href; // use cached href here
})
};

Javascript onclick video object autostart true

How can I change a property of a source element / video object.
In my case I want to change the property autostart from false to true;
html:
<video id="modul_1_video" controls preload="none">
<source id="modul_1_source" src="../video.mp4" type="video/mp4" autostart="false">
</video>
js: (I do not want to use jquery)
modul_1.onclick = function() {
console.log("click works");
document.querySelector("#modul_1_video > source").autostart = true;
}
but it does not seem to work.
why don't you just use the play function?
modul_1.onclick = function() {
console.log("click works");
var video = document.getElementById("#modul_1_video");
video.play();
}
set "autostart" attribute to true on click
document.getElementById('modul_1_source').setAttribute('autostart','true');
modul_1.onclick = function() {
console.log("click works");
document.getElementById("#modul_1_video").setAttribute("autostart","true");
}

dynamically load src for audio and stop after src does not exist

I have songs called *song_1*, *song_2*, *song_3* etc. I want them to play immediately after the previous has finished. That's why I have an "ended" function which plays the next song automatically (works fine so far). The amount of songs I have is obtained dynamically, so I can't tell to stop loading the next src by hardcoding. But when a src does not exist, I get an error, and I cannot replay the songs after finishing etc. How can I prevent this error?
HTML:
<audio id="audio">
<source id="mp3Source" type="audio/mp3" />
</audio>
JQuery:
var audio = $("#audio");
var src = "audio/song_";
var countSongs = 0;
audio.addEventListener("ended", function() {
countSongs++
$('#mp3Source').attr('src', src+countSongs.toString()).detach().appendTo(audio);
audio.play();
});
$('#mp3Source').error(function() {
alert("error");
});
Try this. Getting the native DOM element as jQuery knows nothing about .play() method on the wrapped array returned by the $('#audio') selector:
var audio = $("#audio");
var src = "audio/song_";
var countSongs = 0;
audio.addEventListener("ended", function() {
countSongs++
$('#mp3Source').attr('src', src + countSongs.toString()).detach().appendTo(audio);
audio[0].play();
});
You seem to be a little confused regarding jQuery objects and DOM elements?
$('#audio') probably doesn't have an addEventListener method or a play method, so I'm suprised if that works at all ?
I would suggest something more like
var audio = $("#audio");
var src = "audio/song_";
var countSongs = 0;
audio.on({
ended: function() {
$('#mp3Source').prop('src', src + (++countSongs))
.detach()
.appendTo(audio);
this.load();
this.play();
},
error: function(e) {
alert( JSON.stringify(e) ); // for no console
$(this).off('ended');
}
});

Play one HTML audio element at a time

I have many audio elements on a single page and I want to play just one element at a time. That is if one audio element is playing and I click on play on another element, the previous audio element should pause.
I found a jQuery code from another question to do this but that uses an image as play/pause controls. I'm using the inbuilt controls='controls' attribute for the audio element instead. Is it possible to use jQuery to control the play/pause feature for the audio element in my case?
Here is my HTML code
<div>
<p class="song"><h3><strong>#1 Intro - The Oath</strong></h3><p>
<audio class="playback" src=http://geo-samples.beatport.com/lofi/5005876.LOFI.mp3 controls='controls' preload="none">
<I>Your browser does not support the audio element.</I>
</audio>
</div>
<div>
<p class="song"><h3><strong>#2 A State Of Trance Year Mix 2013</strong></h3></p>
<audio class="playback" src=http://geo-samples.beatport.com/lofi/5005933.LOFI.mp3 controls='controls' preload="none">
<I>Your browser does not support the audio element.</I>
</audio>
</div>
Here is the jQuery code
$(document).ready(function() {
var curPlaying;
$(function() {
$(".playback").click(function(e) {
e.preventDefault();
var song = $(this).next('audio')[0];
if(song.paused){
song.play();
if(curPlaying) $("audio", "#"+curPlaying)[0].pause();
} else { song.pause(); }
curPlaying = $(this).parent()[0].id;
});
});
});
The jQuery code doesn't seem to be working for me.
$(function(){
$("audio").on("play", function() {
$("audio").not(this).each(function(index, audio) {
audio.pause();
});
});
});
See sample at JSFiddle
Vanilla JS solution
Here's a solution that doesn't require jQuery.
function onlyPlayOneIn(container) {
container.addEventListener("play", function(event) {
audio_elements = container.getElementsByTagName("audio")
for(i=0; i < audio_elements.length; i++) {
audio_element = audio_elements[i];
if (audio_element !== event.target) {
audio_element.pause();
}
}
}, true);
}
document.addEventListener("DOMContentLoaded", function() {
onlyPlayOneIn(document.body);
});
Some things to note:
Because this listens for events on a parent element, not on the audio elements themselves, they can be added or removed after the page is loaded and it will still work.
It watches for the play event in the capture phase because play events don't bubble.
More media events are described here on MDN.
Listening for "DOMContentLoaded" should work for most browers.
Little Modification to LostInComputer's Answer
In Your HTML Write:
<audio controls onplay="pauseOthers(this);" >
<source src="SourcePath">
</audio>
In Js Write:
function pauseOthers(ele) {
$("audio").not(ele).each(function (index, audio) {
audio.pause();
});
}
Assuming that your syntax for stopping and pausing tracks is correct (I don't know anything about the audio element), you should be able to do something like this:
$(".playback").click(function(e) {
// pause all other tracks
$('.audio').each(function () {
var song = this;
if (!song.paused) { song.pause(); }
});
// play the audio associated with this element
this.play();
});
<script>
function controlplay(e) {
document.querySelectorAll('.playback').forEach(item => { if(item.id != e.target.id) item.pause(); });
}
</script>
<script>
document.querySelectorAll('.').forEach(item => { item.addEventListener("play", event => { controlplay(event) })});
</script>
Angular:
<audio (play)="audioPlay($event)" controls preload="none">
<source [src]="url" type="audio/mpeg">
</audio>
audioPlay(e) {
let eAudio = this.domService.getDocument.getElementsByTagName('audio')
if (eAudio && eAudio.length > 0) {
for (var i = 0; i < eAudio.length; i++) {
if(e.target !== eAudio[i]){
eAudio[i].pause();
}
}
}
}
<script>
var nowplaying = null;
// Pause and reset playing audio before starting new selection
function pauseRunningAudio(id) {
if ( nowplaying != null && nowplaying != id) {
var x = document.getElementById(nowplaying);
x.pause();
x.load();
}
nowplaying = id;
}
</script>
<!-- id and function value must be the same -->
<audio controls onplay="pauseRunningAudio('song1')" id="song1">
<source src="Bohemian Rhapsody.mp3" type="audio/mpeg">
</audio>
<audio controls onplay="pauseRunningAudio('song2')" id="song2">
<source src="November Rain.mp3" type="audio/mpeg">
</audio>
<audio controls onplay="pauseRunningAudio('song3')" id="song3">
<source src="Smoke on the Water.mp3" type="audio/mpeg">
</audio>

Categories

Resources