Single button toggle for audio using vanilla javascript - javascript

I am trying to make a simple button to turn on and off my audio file.
Once I click play I can't turn it off.
I'm using an image as my button and div.onclick to spark the function.
The html audio tag has id audioPlay.
I use the global boolean playSound, initially set to false.
My script looks like this:
var playSound = false;
if (playSound != true) {
audioButton.src = '../../testStuff/audioPlay.png';
audio.onclick = function () {
document.getElementById('audioPlay').play();
playSound = true;
console.log(playSound);
}
}
if (playSound == true) {
audioButton.src = '../../testStuff/audioStop.png';
audio.onclick = function () {
document.getElementById('audioPlay').pause();
playSound = false;
}
}
When I click on it the first time it works fine. It sets playSound to true.
However, when I go to click it a second time, nothing happens. Something is setting playSound back to false and I don't know why.
I've tried switching the ==true if statement above the false one, as well as rolling both if statements into a single onclick function but it still operates this way.
Any ideas?

I think the issue is that you're adding two separate click handlers that are both being executed on each click. This results in playSound always being set to true, but then immediately being set back to false.
Instead, write a function called togglePlay that does something like the following, and set that as your click handler, but only once.
function togglePlay () {
if (playSound) {
audioButton.src = '../../testStuff/audioStop.png';
document.getElementById('audioPlay').pause();
playSound = false;
} else {
audioButton.src = '../../testStuff/audioPlay.png';
document.getElementById('audioPlay').play();
playSound = true;
}
}

//play is the name of the botton that u click to play the music and psuse
const isplay;
play.addEventListener('click',()=>{
const playmusic = ()=>{
isplay = true;
console.log('play music');
music.play();
};
const pausemusic = ()=>{
isplay = false;
music.pause();
};
if(isplay){
pausemusic();
}else{
playmusic();
};
)};

Related

Play or pause CSS animation using JavaScript

I'm unsure if the following lines of JavaScript are correct. On the click of a button, the following JavaScript function is called. This function should pause the CSS animation when clicked once and resume the animation if clicked again:
function myFunction()
{
document.getElementById("sky").style.animationPlayState = "paused | running";
}
The logic for determining what state to change it to, needs to be done outside the quotes. You are probably looking more for something like this:
function myFunction()
{
var sky = document.getElementById("sky");
if(sky.style.animationPlayState == "paused")
{
sky.style.animationPlayState = "running";
}
else
{
sky.style.animationPlayState = "running";
}
}
Or all in one line like this:
element.style.animationPlayState = running ? 'paused' : 'running';

How do i add a Play/Pause button for this slideshow?

Hi im trying to make a slideshow that run automatically and with this code it's working but i need to add a Play/Pause button to that code. Someone care to help ?
I would need the html/css also
var indexDiaporama=1;
afficherDiapo(indexDiaporama);
function ajoutDiapo(n){
afficherDiapo(indexDiaporama+=n);
}
function diapoActuelle(n){
afficherDiapo(indexDiaporama=n);
}
function afficherDiapo(n){
var i;
var slides=document.getElementByClassName("diapo");
var dots=document.getElementByClassName("dot");
if(n>slides.length){indexDiaporama=1;}
if(n<1){indexDiaporama=slides.length;}
for(i=0; i<slides.length; i++){
slides[i].style.display="none";
}
for(i=0; i<dots.length; i++){
dots[i].className=dots[i].className.replace("active", "");
}
slides[indexDiaporama-1].style.display="block";
dots[indexDiaporama-1].className+="active";
}
var timer = setInterval(function(){
indexDiaporama++;
afficherDiapo(indexDiaporama);
},3000);
Start by setting a variable, we will call it pause, to false and then run a conditional inside your setTimeout() that checks if it is false => if(!paused){ //run code }.
Handle the paused variable due to what state your button is in when it is pressed ==> e.target
You create a function that passes in your event target of a pause/play button when it is clicked. In that function you check the value of your pause/play button, you can use a dataset to toggle 0 or 1 / on or off / true or false on click and change the value of your pause variable due to what that dataset is set to on click.
In my example I use 0 and 1 in the data-id attribute => dataset.id in JS, with a conditional that checks that value => if (e.target.dataset.id === '0'){ //set paused to true }else{ // set paused to false }. Within the conditional I also set the textContent of the button and the dataset.id value as well.
Then each time you press the pause button the setInteral freezes as it is looking for paused to not be set to false => if (!paused){ // run code for setInterval }.
Below is a simply JS setInterval that increments a number by one every millisecond. We can pause and play it using the function and event listener as described above.
const display = document.getElementById('display')
const btn = document.querySelector('.btn')
let paused = false;
let i = 1;
function checkBool(e) {
if (e.target.dataset.id === '0') {
e.target.dataset.id = '1'
btn.textContent = 'Play'
paused = true;
}else{
e.target.dataset.id = '0'
btn.textContent = 'Pause'
paused = false;
}
}
btn.addEventListener('click', checkBool)
const timer = setInterval(function() {
if (!paused) { //<-- paused is not false
//<-- run the code your interval handles
display.textContent = i;
i++;
}
}, 100);
<div id="display"></div>
<button class="btn" data-id="0">Pause</button>

'if' statement and eventListener question

I'm building a website and right now I'm having an issue trying to get an if statement to read a change of state variable.
I'm trying to close my navbar menu when I click anywhere in the body, other than the navbar. However, my if statement that contains the event listener for the body will not execute because (I think) that the change of state variable that is being used for the condition (true when menu is open, false when menu is closed) is just not being read.
When I open the nav menu, the change of state variable changes to true, as it is intended to. When I close the menu using the button on the nav bar, the change of state variable changes to false, as it is intended to.
Here's my code:
"use strict";
const btnNav = document.querySelector(".nav-btn--container");
const linkContainer = document.querySelector(".link-container");
const header = document.querySelector(".header");
const sidebar = document.querySelector(".sidebar");
const bodyChildren = header.parentElement.children;
const navBtn = document.querySelector(".nav-btn");
const menu = document.querySelector(".sidebar__menu");
const body = document.querySelector(".container");
/**** change of state variables ****/
let menuIsOpen = false;
/**** functions ****/
const closeMenu = function () {
addRemoveBlur("remove");
navBtn.classList.remove("nav-btn--opened");
sidebar.classList.remove("blur");
navBtn.classList.add("nav-btn--closed");
menu.style.visibility = "hidden";
menu.style.transform = "translateX(-150%)";
menuIsOpen = false;
};
const openMenu = function () {
addRemoveBlur("add");
navBtn.classList.remove("nav-btn--closed");
navBtn.classList.add("nav-btn--opened");
menu.style.visibility = "visible";
menu.style.transform = "translateX(0%)";
menuIsOpen = true;
};
const closeMenuByBody = function (e) {
const click = e.target;
closeMenu();
};
const openCloseMenu = function () {
if (!menuIsOpen) {
openMenu();
return;
}
if (menuIsOpen) {
closeMenu();
return;
}
};
/**** this is the problem ****/
if (menuIsOpen) {
body.addEventListener("click", function (e) {
closeMenuByBody(e);
});
}
The problem is that the event listener is never initialized, as your menuIsOpen variable is always declared false.
You should switch your if statement to be contained within the click event handler, like so:
body.addEventListener("click", function (e) {
if (menuIsOpen) {
closeMenuByBody(e);
}
});
You should also consider the following changes to your openCloseMenu method (here renamed to toggleMenu):
const toggleMenu = function () {
if (menuIsOpen) {
closeMenu();
} else {
openMenu();
}
};
As you are evaluating a boolean value, there is no need to test it in two different if expressions: you check if it's true and do something if it is, or else you do something knowing that it's false.
You could also remove your closeMenuByBody method, and just call the closeMenu method from your event listener, as you aren't doing anything in it appart from that:
body.addEventListener("click", function (e) {
if (menuIsOpen) {
e.preventDefault();
closeMenu();
}
});

How to have multiple instances of a jQuery plugin

I am trying to create a SoundCloud music player. It can play any track from SoundCloud, but this plugin is only working if there is only one instance of it in the page. So it wont work if two of the same plugin are in the page.
Here is an example of having two players in the page: JSFiddle
var trackURL = $(".player").text();
$(".player").empty();
$(".player").append("<div class='playBTN'>Play</div>");
$(".player").append("<div class='title'></div>");
var trackId;
SC.get('/resolve', { url: trackURL }, function (track) {
var trackId = track.id;
//var trackTitle = track.title;
$(".title").text(track.title);
$(".playBTN").on('click tap', function () {
//trackId = $(".DSPlayer").attr('id');
stream(trackId);
});
// first do async action
SC.stream("/tracks/" + trackId, {
useHTML5Audio: true,
preferFlash: false
}, function (goz) {
soundToPlay = goz;
sound = soundToPlay;
scTrack = sound;
//updater = setInterval( updatePosition, 100);
});
});
var is_playing = false,
sound;
function stream(trackId) {
scTrack = sound;
if (sound) {
if (is_playing) {
sound.pause();
is_playing = false;
$(".playBTN").text("Play");
} else {
sound.play();
is_playing = true;
$(".playBTN").text("Pause");
}
} else {
is_playing = true;
}
}
If you remove any of these div elements that hold the .player class, the other element will work. So it only doesn't work because there are two instances of the same plugin.
How can I fix it? to have multiple instances of the player in one page?
I have identified the problem. It has to do with the fact that you are trying to load multiple tracks at the same time, but have not separated the code to do so.
As #Greener mentioned you need to iterate over the .player instances separately and execute a SC.get() for each one of them.
Here is what I see happening that is causing the problem:
var trackURL = $(".player").text();
^The code above returns a string that contains both of the URLs you want to use back-to-back without spaces. This creates a problem down the road because of this code:
SC.get('/resolve', { url: trackURL }, function (track) {...
That is a function that is trying to load the relevant song from SoundCloud. You are passing it a variable "trackURL" for it to try and load a specific URL. The function gets a string that looks like "URLURL" what it needs is just "URL".
What you can do is iterate over all the different ".player" elements that exist and then call the sounds that way. I modified your script a little to make it work using a for loop. I had to move the "empty()" functions into the for loop to make it work correctly. You have to use .eq(index) when referring to JQuery array of elements.
Like this:
var trackURL
var trackId;
for(index = 0; index < $(".player").length; index++){
trackURL = $(".player").eq(index).text();
//alert(trackURL);
$(".player").eq(index).empty();
$(".player").eq(index).append("<div class='playBTN'>Play</div>");
$(".player").eq(index).append("<div class='title'></div>");
SC.get('/resolve', { url: trackURL }, function (track) {
var trackId = track.id;
alert(track.id);
//var trackTitle = track.title;
$(".title").eq(index).text(track.title);
$(".playBTN").eq(index).on('click tap', function () {
//trackId = $(".DSPlayer").attr('id');
stream(trackId);
});
// first do async action
SC.stream("/tracks/" + trackId, {
useHTML5Audio: true,
preferFlash: false
}, function (goz) {
soundToPlay = goz;
sound = soundToPlay;
scTrack = sound;
//updater = setInterval( updatePosition, 100);
});
});
}
This is not a completely finished code here, but it will initiate two separate songs "ready" for streaming. I checked using the commented out alert what IDs SoundCloud was giving us (which shows that its loaded now). You are doing some interesting stuff with your streaming function and with the play and pause. This should give you a good idea on what was happening and you can implement your custom code that way.

Repetitive javascript call. can not disable

I use a JavaScript function to change the page when a function is clicked. An ajax call is made inside the function.
As the browser is slow. If I click more than one time on the button before the page changes (AJax div load. Page actually not changed), an ajax call is made for each click.
I used the following method to prevent. But even it is called many times. How can I prevent it?
var isClicked = function() {}
isClicked.init = function() {
this.clicked = false;
}
function myAjaxFunction {
//some statements
if(isClicked.clicked == 'undefined')
isClicked.clicked = false;
if(isClicked.clicked)
return false;
isClicked.clicked = true;
// my ajax call here
isClicked.clicked = false;
//some statements
}
var isClicked = false;
function AjaxFunction(){
if(isClicked){
return false;
}
// Set your variable.
isClicked = true;
// Do yourAjaxCall and use isClicked = false in the callback of that function.
}

Categories