saving both checkbox and audio state to local storage - javascript

I am trying to save to local storage the state of both a checkbox (checked/unchecked) and audio (play/pause). The default state of the checkbox is checked and audio is playing (looping) as seen in the code below.
So if the checkbox is checked, audio is playing and both should be saved to local storage (checkbox checked and audio playing).
Else if the checkbox is unchecked, audio is paused and both should be saved to local storage (checkbox unchecked and audio paused).
The problem I have is with saving the state of the checkbox and audio after it's been checked again.
Steps in reproducing the issue:
1) uncheck checkbox > audio stops > refresh browser > works
2) check checkbox > audio playing > refresh browser > not working, checkbox unchecked and audio not playing
Here is the javascript:
if (window.localStorage.getItem("musicState") != null) {
var music = window.localStorage.getItem("musicState");
if (music == "true") {
status = 'pause';
$("audio").trigger(status);
}
else {
status = 'pause';
$("audio").trigger(status);
$("input:checkbox[name='music']").removeAttr("checked");
}
}
$("input:checkbox[name='music']").click(function () {
var visMusic = "play";
if (status == 'pause') {
status = 'play';
} else {
status = 'pause';
}
$("audio").trigger(status);
window.localStorage.setItem("musicState", visMusic)
});
here is the HTML:
<audio autoplay loop>
<source src="audio/music.mp3" type="audio/mpeg">
</audio>
<label><input type="checkbox" name="music" checked></label>

In your checkbox's click callback you are setting visMusic as "play". You never update it before storing it in localStorage as "musicState". This means that no matter what you do, "musicState" is always going to equal "play".
In your if-statement at the top (where you are retrieving from localStorage) you are testing if what you stored is "true". It is not, and never will be, because it is always "play". Your code is always going to your else which pauses the music and unchecks the box.
Here is an updated version that should work:
if (window.localStorage.getItem("musicState") != null) {
var music = window.localStorage.getItem("musicState");
if (music == "true") {
status = 'play';
$("audio").trigger(status);
}
else {
status = 'pause';
$("audio").trigger(status);
$("input:checkbox[name='music']").removeAttr("checked");
}
}
$("input:checkbox[name='music']").click(function () {
var visMusic = "false";
if (status == 'pause') {
status = 'play';
visMusic = "true";
} else {
status = 'pause';
}
$("audio").trigger(status);
window.localStorage.setItem("musicState", visMusic)
});

Related

Unable to set Checkbox to Checked after refreshing and storing in Local Storage

I am currently facing an issue where I am unable to set a input box to stay checked after a refresh. I have stored the values in the local storage, even though the value is stored in the local storage; the checkbox does not remain checked. Please do help me on this! Thank you
Here is the html code:
<div style="color: #005e95">
<input type="checkbox" id="checkboxFullDownload" data-dojo-attach-event="onClick: _test" style="cursor: pointer;" >
Full Download
</div>
Here is the JS code:
_test: function(){
let checkBox = document.getElementById("checkboxFullDownload")
if(localStorage.getItem(`${xmlTitle} ID:${this.item._id}`) === "AllowFullDownload"){
checkBox.setAttribute("checked",true)
console.log("set to true")
}
if(checkBox.checked){
console.log("Checked")
localStorage.setItem(`${xmlTitle} ID:${this.item._id}`,"AllowFullDownload")
checkBox.checked = true;
}
if(!checkBox.checked){
console.log("Unchecked")
localStorage.removeItem(`${xmlTitle} ID:${this.item._id}`)
checkBox.setAttribute("checked",false)
}
}
If you want to check the checkbox on pageload then localStorage.getItem() must be out of scope of any functions which are executed on certain events.
let checkBox = document.getElementById("checkboxFullDownload");
_test: function() {
if (checkBox.checked) {
console.log("Checked");
localStorage.setItem(`${xmlTitle} ID:${this.item._id}`, "AllowFullDownload");
checkBox.checked = true;
}
if (!checkBox.checked) {
console.log("Unchecked");
localStorage.removeItem(`${xmlTitle} ID:${this.item._id}`);
checkBox.checked = false;
}
}
if (localStorage.getItem(`${xmlTitle} ID:${_test.item._id}`) === "AllowFullDownload") {
checkBox.checked = true;
console.log("set to true");
}
Replace checkBox.setAttribute("checked",true) with checkBox.checked = true

addEventListener click being fired multiple times within a flickity slider

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.

Conditional checkbox action for Tone.js (Web Audio)

I'm trying to create a checkbox ($('#button')) the action of which changes depending on the state of player (whether the audio is playing or not) using Tone.js and jQuery.
So, the logic is that if the audio is already started, then the action of the checkbox is simply to mute (or unmute) the audio. However, if the audio is not already started then I want the checkbox to start player (with the default player.mute == false) and change its own action to mute/unmuting. This will mean that, once the player.state == started you cannot change it , only toggle whether it is muted or not.
I've managed to get a function together that toggles the state or the mute value, but not one where the action of the checkbox itself is conditioned by the state. The code I have below is my attempt at this but it doesn't seem to work ☚ī¸ – any help would be really appreciated.
const button = $('#button');
if(player.state == 'started') {
$(button).attr('checked', true);
} else if(player.state == 'stopped') {
$(button).attr('checked', false);
}
if(player.state == 'started') {
$(button).change(function(){
if(player.mute == true) {
player.mute == false;
$(this).attr('checked', true);
} else if(player.mute == false) {
player.mute == true;
$(this).attr('checked', false);
}
});
} else if(player.state == 'stopped') {
$(button).change(function(){
player.start();
$(this).attr('checked', true);
});
}
Just for context: This is all because whether autoplay is allowed or not varies between browsers. In some an autoplay function I have earlier in the script means that the player begins on the page load (👍đŸŧ), in others an explicit user action is required (👎đŸŧ).
What i understood is, the desired behavior is as follows:-
Whenever the player.state === 'started'
Clicking on the button should mute the audio and again clicking on it should unmute the audio. and keep on toggling till the player.state === 'started'
If player.state === 'stopped', clicking on button should start the audio and then keepo toggling the mute/unmute till the player is in started state.
Below is the implementation of the same.
const button = $('#button');
//First set the button state to checked on unchecked depending on state
if(player.state == 'started') {
button.attr('checked', true); //this means now the player is playing musing and is unmute.
} else if(player.state == 'stopped') {
button.attr('checked', false); //this means now the player is stopped and is also mute
}
button.change(function(){
if(player.state === 'started') {
if(player.mute) {
player.mute = false;
button.attr('checked', false);
} else {
player.mute = true;
$(this).attr('checked', true);
}
} else if (player.state === 'stopped') { //button was clicked and player is in stopped state. so start the player and turn on the checkbox so it displays that it is playing and is unmute
player.start();
button.attr('checked', true);
}
});
//with this implementation, on checkbox implies unmute and started state.
//off checkbox implies stopped or started+mute state.

How to check whether a video is audible?

A video has audio track and its volume is not zero or muted, but this video is not audible due to its audio track is in total quietness. I want to know how to check whether a video is audible, so I can toggle functions upon.
I found how to check whether a video has audio track from here. #upuoth's method works most browsers except IE10+. #brefd.it works for IE10+ but I didn't know how to use his code (please explain to me)
#upuoth's code
document.getElementById("video").addEventListener("loadeddata", function() {
if (typeof this.webkitAudioDecodedByteCount !== "undefined") {
// non-zero if video has audio track
if (this.webkitAudioDecodedByteCount > 0)
console.log("video has audio");
else
console.log("video doesn't have audio");
}
else if (typeof this.mozHasAudio !== "undefined") {
// true if video has audio track
if (this.mozHasAudio)
console.log("video has audio");
else
console.log("video doesn't have audio");
}
else
console.log("can't tell if video has audio");
});
#brefd's code
function hasAudio (video) {
return video.mozHasAudio ||
Boolean(video.webkitAudioDecodedByteCount) ||
Boolean(video.audioTracks && video.audioTracks.length);
}
var video = document.querySelector('video');
if(hasAudio(video)) {
console.log("video has audio");
} else{
console.log("video doesn't have audio");
}
I prepared three video clips, one with an audio track, one without audio track and one with an audio track but isn't audible. The code I found above only works for the fisrt two clips but for the third one. Please let the alert be "not audible" when playing the third clip by using the code from JSfiddle link.
Below is the merged code of above that you can replace with in your JSFiddle:
document.getElementById("myVideo").addEventListener("loadeddata", function() {
if (typeof this.webkitAudioDecodedByteCount !== "undefined") {
if (this.webkitAudioDecodedByteCount > 0)
alert("This video has a track");
else
alert("no track");
} else if (typeof this.mozHasAudio !== "undefined") {
if (this.mozHasAudio)
alert("This video has a track");
else
alert("no track");
} else if (typeof this.audioTracks !== "undefined") {
if (this.audioTracks && this.audioTracks.length)
alert("audible");
else
alert("not audible");
} else
alert("Not sure");
});
Unfortunately, I doubt if there would be a way to detect "not audible" audio tracks.
There are different ways to check whether a video file has audio or not, one of which is to use mozHasAudio, video.webkitAudioDecodedByteCount and video.audioTracks?.length properties of video, clean and simple...
const video = component.node.querySelector("video");
video.onloadeddata = function() {
if ((typeof video.mozHasAudio !== "undefined" && video.mozHasAudio) ||
(typeof video.webkitAudioDecodedByteCount !== "undefined" && video.webkitAudioDecodedByteCount > 0) ||
Boolean(video.audioTracks?.length)) {
console.log("This video has audio tracks.");
} else {
console.log("This video has no audio tracks.");
}
};

Changing the text of a button according to whether media is playing or paused?

My code partially works. When I click play it changes to paused, but when I click pause right after it just stays as pause and doesn't change back to play?
var playOrPause = function (id, button) {
var pp = document.getElementById(id);
if(pp.paused) {
button.textContent = 'Play';
} else if(!pp.paused) {
button.textContent = 'Pause';
}
};
I just figured out my problem. I coded one of my event listeners wrong lol Thank you guys for the help!!
$('.player_audio').click(function() {if (this.paused == false) { this.pause();
alert('music paused'); } else { this.play();alert('music playing');}});
This will help you

Categories

Resources