One Script for multiple buttons - javascript

I've got a soundboard I use at work to annoy coworkers. It has multiple buttons, that play or stop a sound. Right now each button has its own script to play the sound. So I'm up to 47 sounds on the page and have to write this script for each one. I'd like to clean that up and have a one smarter script that works for all of them.
my buttons look like:
<button onclick="javascript:toggleSound1();">I don't know what we're yelling about.</button>
Then I have the definition of the audio element:
<audio id="sound1" src="sounds/dontknowwhatwereyellingabout.wav"></audio>
and the script:
<script type="text/javascript">
function toggleSound1() {
var audioElem = document.getElementById('sound1');
if (audioElem.paused)
audioElem.play();
else
audioElem.pause(); audioElem.currentTime = 0;
}
</script>
So it seems to me that if i could define the 'sound1' on the press in each button the same script should work for each button. as I have it now I have to define 'sound1' 'sound2' 'sound3' and so on, and point a new 'togglesound' at each of them.

You could rewrite toggleSound1 to take an argument:
function toggleSound(num) {
var audioElem = document.getElementById('sound' + num); // append the number to "sound" (sound1, sound2, etc.)
if (audioElem.paused) {
audioElem.play();
} else {
audioElem.pause();
}
audioElem.currentTime = 0;
}
Then to use it, you could just pass the number to the function:
<button onclick="javascript:toggleSound(1);">I don't know what we're yelling about.</button>

I'm not sure how I feel about encouraging this, but...
<button onclick="toggleSound('sound1');">I don't know what we're yelling about.</button>
<button onclick="toggleSound('sound2');">Some other sound</button>
<script type="text/javascript">
function toggleSound1(soundId) {
var audioElem = document.getElementById(soundId);
if (audioElem.paused)
audioElem.play();
else
audioElem.pause(); audioElem.currentTime = 0;
}
</script>

a better way is to use event delegation, and put the event handler higher up
<div onclick="handleAudio(e)">
<button data-audio="1">I don't know what we're yelling about.</button>
<button data-audio="2">Some other sound</button>
</div>
function handleAudio(e) {
var audio = document.getElementById('sound' + e.target.dataset.audio);
audio.play();
}

Related

JavaScript For Loop not returning anything (not running)?

Ok so, I've got this for loop in a script tag on my EJS page. The current code looks like this:
<script async>
var removeCartItemButtons = document.getElementsByClassName('btn-danger')
console.log(removeCartItemButtons)
var i;
for (i = 0; i < removeCartItemButtons.length; i++){
console.log('elem')
var button = removeCartItemButtons[i]
button.addEventListener('click', function() {
console.log('clicked')
})
}
</script>
The console.log for the removeCartItemButtons works but the console.log('elem') doesn't run. There are no errors in my cmd nor on the developer tools. I've looked online at different forums to find people doing similar things to me and their's work fine.
I've tried multiple things, and an extra notice is that this is inside the html file and not external.
The end goal of this for loop is to loop through every element with class 'btn-danger' and log when they are clicked.
Any help would be amazing!
try running document.getElementsByClassName('btn-danger') in the console.
Additional tip: there is a for of loop in js
check this: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Statements/for...of
basically:
for(let button of removeCartItemButtons) {
button.addListener
}
I tried this code in Codepen and it worked. I rewrite your code but technically, just used a different syntax. "async" in your script tag can cause the problem, I can't be sure.
var buttons = document.querySelectorAll('.btn-danger');
[...buttons].forEach(button => {
console.log('elem')
button.addEventListener('click', function() {
console.log('clicked')
})
})
There must be an issue with your HTML code. Run the snippet below, it's working fine
var removeCartItemButtons = document.getElementsByClassName('btn-danger')
console.log(removeCartItemButtons)
var i;
for (i = 0; i < removeCartItemButtons.length; i++) {
console.log('elem')
var button = removeCartItemButtons[i]
button.addEventListener('click', function() {
console.log('clicked');
alert('clicked');
})
}
<button class='btn-danger'>Button</button>
<br/>
<button class='btn-danger'>Button</button>
<br/>
<button class='btn-danger'>Button</button>
<br/>
<button class='btn-danger'>Button</button>
removeCartItemButtons.length is 0 because when the snippet ran the DOM was not fully loaded.
Remove async and put your script at the end of your html.
Another option is to use an EventListener like onload to make sure your buttons exist before changing them.

Javascript HTML play sound only once, but more strange thing happened

I tried this simple snippet in codepen. and function once1 can play as many times as you want while once2 can play sound only once.
Anyone know what's the difference?
var simple = new
Audio("http://s3.amazonaws.com/freecodecamp/simonSound1.mp3" );
var birdSound = new
Audio('http://www.noiseaddicts.com/samples_1w72b820/4929.mp3');
birdSound.loop = false;
simple.loop = false;
function once1(){
birdSound.play();
};
function once2(){
simple.play();
};
Here you go, I saw the other answer still wasn't working on jsfiddle or codepen so try this!
var simple = new
Audio("http://s3.amazonaws.com/freecodecamp/simonSound1.mp3" );
var birdSound = new
Audio('http://www.noiseaddicts.com/samples_1w72b820/4929.mp3');
birdSound.loop = false;
simple.loop = false;
function once1(){
birdSound.load();
birdSound.play();
};
function once2(){
simple.load();
simple.play();
};
Just use .load :D
Update: Using the load() method, as suggested by the other poster, I can get the code below to repeatedly play the second sound in Chrome, but it still sounds different than it does in Firefox. In Firefox the sound plays smoothly, but in Chrome the sound ends more abruptly, with a little bit of a crackle or click. I suspect that there's just something about this particular sound file that isn't fully compatible with Chrome.
I'm able to get both sounds to play as many times as I want in Firefox with this Plunker here, but not in Chrome: http://plnkr.co/edit/gM8lobVoQoAtVSlwVZNC?p=preview
function init() {
var simple = new Audio("http://s3.amazonaws.com/freecodecamp/simonSound1.mp3" );
var birdSound = new Audio('http://www.noiseaddicts.com/samples_1w72b820/4929.mp3');
birdSound.loop = false;
simple.loop = false;
function once1() {
birdSound.play();
}
function once2() {
simple.load();
simple.play();
}
var btn1 = document.getElementById("one");
btn1.addEventListener('click', once1);
var btn2 = document.getElementById("two");
btn2.addEventListener('click', once2);
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body onload="init()">
<button id="one">Sound 1</button><br>
<button id="two">Sound 2</button>
</body>
</html>
Which web browser were you using?

Javascript if statements in displaying images

Hey i am currently trying to get a program running in javascript i want the program to display the 4 images one after each other with the single press of a button and then after the 4 images have cycled through i want them to stop cycling and i cant seem to do it this is my code i currently have:
<html>
<head>
<script>
var images = ["image1.png","image2.png","image3.png","image4.png"];
var imagenum = 0;
var timer;
function imageCycle()
{
if(++imagenum == 4)
imagenum = 0;
document.image.src = images[imagenum];
timer = setTimeout("imageCycle()",1000);
}
</script>
</head>
<body>
<img src="image1.png" name="image" width=800 height=600>
<form>
<input type="button" value="images" name="cycle images" onclick="imageCycle()">
</form>
</body>
</html>
any help is appreciated many thanks!
In your code you continue to schedule the function, that's why the images continue to rotate.
If you want to stop at the forth image displayed, you have to put the setTimeout line in an else statement.
if (++imagenum == 4) {
imagenum = 0;
} else {
document.image.src = images[imagenum];
timer = setTimeout("imageCycle()",1000);
}
Another point, that other users notice and I just report here in my answer.
You use the string:
imageCycle()
as the first argument of setTimeout, insted you should use just the function name.
timer = setTimeout(imageCycle, 1000);

$("#id").click(function(){calculation()});

What is wrong with the line in the header?
The below example is supposed to make a button which will increment a counter each time it is clicked. However, I enforce a delay of 2000 ms between button clicks. The version below works, however, if I use the commented out line instead of
document.getElementById("rollButton").onclick=function(){calculation()};
(both in function afterWaiting())
I get various odd results, for instance that the counter starts incrementing by a lot more than 1, and the waiting time disappears?
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>
function afterWaiting()
{
$("#rollButton").css("color","black");
//$("#rollButton").click(function(){calculation()});
document.getElementById("rollButton").onclick=function(){calculation()};
}
var counter=0;
function calculation()
{
////Enforcing wait:
document.getElementById("rollButton").style.color="red";
document.getElementById("rollButton").onclick="";
window.setTimeout("afterWaiting()",2000);
counter=counter+1;
document.getElementById("test").innerHTML=counter;
}
</script>
</head>
<body>
<button type="button" onclick="calculation()" id="rollButton"> Roll! </button>
<p id="test"> </p>
</body>
</html>
What have I misunderstood?
thanks in advance :)
JSFiddle:
http://jsfiddle.net/Bwxb9/
The difference is that when you apply event handlers through onclick as you do in your original version, you can only bind one handler to the element. And using onclick="" kind of clears it.
When using jQuery .click(handler) you bind a new handler each time you call it (and you can unbind it with unbind('click') (and not with onclick=""). So after a couple of calls to afterWaiting you have applied mulitple click handlers on your element, and on each click the calculation function runs multiple times..
So, one way to correct it is to replace
document.getElementById("rollButton").onclick="";
with
$('#rollButton').unbind('click');
The only code required is
<button type="button" id="rollButton"> Roll! </button>
<p id="test"> </p>
var counter = 0;
var $test = $('#test');
var $rollButton = $('#rollButton');
function increment(){
$test.html(counter++);
$rollButton.off('click', increment);
setTimeout(function(){
$rollButton.on('click', increment);
}, 2000);
}
$rollButton.on('click', increment);
Demo: Fiddle
Updated: as suggested by Andy, but I would recommend Andy's answer as it involves no additional event manipulation
var counter = 0;
var $test = $('#test');
var $rollButton = $('#rollButton');
function increment(){
$test.html(counter++);
setTimeout(function(){
$rollButton.one('click', increment);
}, 2000);
}
$rollButton.one('click', increment);
Demo: Fiddle
That's generally a bit of an odd and confusing approach.
Here's how i'd do it, without mixing jquery and pure js (onclick) too much:
http://jsfiddle.net/LGvKS/
var wait = false;
counter = 0;
$('button').click(function(){
if(!wait){
$('span').text(++counter);
wait=true;
setTimeout(function(){
wait=false;
},2000);
}
});

Javascript Sound Start/Stop and Image Change

I am new to JS and I have a pretty simple-seeming problem.
I want to have a small image that when clicked changes to a different image and at the same time begins playing a looped sound file. When the image is clicked a second time it changes back to the original image and also stops the sound file.
You can think of it as a button that says "start". when "start" is clicked it loops the sound and changes to "stop" and when "stop" is clicked it goes back to start and the sound ceases playing.
I've gotten as far as creating none-displayed checkbox inside of a label which is a square that when checked plays sound and when unchecked stops sound. Problem is I can't get the checkbox to change into different images with "check", "uncheck".
I've also got some code that has a link change images, but I cannot figure out how to make it play the sound.
SO basically i need to combine these two things. BUT I CAN'T figure out how. And I've been googling for the past two days nonstop but cannot find a clearcut and simple answer.
It may help to know that I plan on having many of these small clickable images on the same page, so the Javascript needs to be able to be light but effect all of the links or divs or whatever they are in the end.
Sorry for such a long question. Anybody?
Thanks in advance!
<html>
<head>
<script type="text/javascript">
var pos = 0
var sId = 'sound';
function change() {
if(pos == 0) {
pos = 1;
document.getElementById('btn').src="http://www.buzzingup.com/wp-content/uploads/2011/07/stop.png";
var e = document.createElement('embed');
e.setAttribute('src','beep.mp3');
e.setAttribute('id',sId);
e.setAttribute('hidden','true');
e.setAttribute('autostart','true');
e.setAttribute('loop','true');
document.body.appendChild(e);
} else {
pos = 0;
document.getElementById('btn').src="http://geekoffices.com/wp-content/uploads/2011/07/start-button-300x299.png";
document.body.removeChild(document.getElementById(sId));
}
}
</script>
</head>
<body>
<img src="http://geekoffices.com/wp-content/uploads/2011/07/start-button-300x299.png" onClick="change()" id="btn" />
</body>
</html>
How about that, I think it should work.
Edit:
Here is an OO version that should do what you need:
<html>
<head>
<script type="text/javascript">
function imageSwitch(_imgID,_imgStart,_imgStop,_soundFile) {
this.imgID = _imgID;
this.imgStart = _imgStart;
this.imgStop = _imgStop;
this.soundFile = _soundFile;
this.pos = 0;
this.e;
this.change = function() {
if(this.pos == 0) {
this.pos = 1;
document.getElementById(this.imgID).src = this.imgStop;
this.e = document.createElement('embed');
this.e.setAttribute('src',this.soundFile);
this.e.setAttribute('id','sound'+this.imgID);
this.e.setAttribute('hidden','true');
this.e.setAttribute('autostart','true');
this.e.setAttribute('loop','true');
document.body.appendChild(this.e);
} else {
this.pos = 0;
document.getElementById(this.imgID).src = this.imgStart;
this.e.parentNode.removeChild(this.e);
}
}
}
</script>
<script type="text/javascript">
var abc = new imageSwitch('btn1','http://geekoffices.com/wp-content/uploads/2011/07/start-button-300x299.png','http://www.buzzingup.com/wp-content/uploads/2011/07/stop.png','beep.mp3');
var def = new imageSwitch('btn2','http://geekoffices.com/wp-content/uploads/2011/07/start-button-300x299.png','http://www.buzzingup.com/wp-content/uploads/2011/07/stop.png','beep.mp3');
</script>
</head>
<body>
<img src="http://geekoffices.com/wp-content/uploads/2011/07/start-button-300x299.png" onClick="abc.change()" id="btn1" />
<img src="http://geekoffices.com/wp-content/uploads/2011/07/start-button-300x299.png" onClick="def.change()" id="btn2" />
</body>
</html>

Categories

Resources