How to stop an onended function onclick - javascript

I have an onclick shuffle function that executes everytime the audio finishes. It works all fine, but I want to make another button that stops its execution.
Please please help with an example
Full Code:
<button onclick="test();stats();auto()">Shuffle</button>
<button id="abort" onclick='exitauto()'>Stop Shuffle</button>
<script>
function exitauto(){
}
</script>
<script>
function stats() {
if(document.getElementById("audio").src == "test.mp3")
{
document.getElementById("p2").innerHTML = "some song";
document.getElementById("playerimg").src="img.png";
};
}
</script>
<script>
function auto(){
var aud = document.getElementById("audio");
aud.onended = function shuf() {
test();
stats();
};
}
</script>
<script>
function test() {
var values = ['test.mp3',
],
valueToUse = values[Math.floor(Math.random() * values.length)];
document.getElementById("audio").pause();
document.getElementById("audio").setAttribute('src', valueToUse);
document.getElementById("audio").load();
document.getElementById("audio").play();
};
</script>

You can add a global variable which can be used to decide whether to call the test() and stats() function in the auto function or not. You can set that variable to true when clicked on start and false when clicked on stop

Related

How to make a toggle variable persist?

I'm working on a quiz page where I have a timer that I would like to be able to toggle on or off so it doesn't distract the user, and save the setting after submitting an answer. The timer function works, and calls on localStorage.getItem(). But when I try the below with a boolean to see if the showHideTimer() button is clicked, the timer always shows up when the next question appears. The console always logs true when the page loads a new question.
<script>
var clickCookie = 'clicked';
var clicked = localStorage.getItem(clickCookie);
console.log(clicked);
function showHideTimer(){
if(clicked==true){
document.getElementById("testHeaderRight").style.color = "black";
clicked=false;
localStorage.setItem(clickCookie, clicked);
console.log(clicked);
return clicked;
}
else{
document.getElementById("testHeaderRight").style.color = "white";
clicked=true;
localStorage.setItem(clickCookie, clicked);
console.log(clicked);
return clicked;
}
};
window.onload = function(){
if(clicked===null){
localStorage.setItem(clickCookie, false);
} else {
showHideTimer(clickCookie);
}
};
</script>
<body>
<button id="showHideTimer" onclick="showHideTimer()">Toggle Timer</button>
<div id="testHeaderRight">
Time Remaining :
<span id="time"></span>
</div>
<script>
var cookieName = 'startTimer';
var savedSeconds = localStorage.getItem(cookieName);
function startTimer(duration, display) {
var timer = duration, seconds;
setInterval(function () {
seconds = parseInt(timer);
display.textContent = secondsToHms(seconds);
var runningTime = (parseInt(seconds));
localStorage.setItem(cookieName, runningTime);
}, 1000);
}
window.onload = function () {
var startTime = 7200,
display = document.querySelector('#time');
if (savedSeconds === null){
startTimer(startTime, display);
} else {
startTimer(savedSeconds, display);
}
};
</script>
</body>
I've tried moving the window.onload call into the same function as the timer since that is functioning properly, but seems to make no difference. I've tried switching the clicked=true/false; variables around to make sure I'm not confusing myself with booleans, and they switch freely in the console when clicking on the button. I've tried changing the return value of the showHideTimer() function to be localStorage.setItem(clickCookie, clicked);
When you get the item out of storage it's a string, "true", not a boolean.
So your if(clicked==true) comparison never passes and you end up on the "false" path every time.

Function inside event listener triggers only on it's initialization

var init = true;
$('#btn').on('click', delay(function() {
$('#text').append('click');
init = false;
}, 100));
function delay(fn, ms, enabled = true) {
$('#text').append(init);
// if(init) disable delay
let timer = 0;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(fn.bind(this, ...args), ms || 0);
}
}
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<button id='btn'> TRIGGER </button>
<div id="text"></div>
Init is a global variable which is meant to be used inside delay function to disable delay (init true/false) only on event listener initialisation.
The problem is that the delay function is triggered only once and ignores the change (to false) of the init variable.
For example, try clicking the trigger button. The init variable value is printed only for the first time.
You are calling the delay function in a wrong way in the click handler. You have to call it like so:
$('#btn').on('click', function () {
delay(function() {
$('#text').append('click');
init = false;
}, 100);
});
You will have to check for the value of init inside the function, like this:
$('#btn').on('click', delay(function() {
if(init) {
$('#text').append('click');
init = false;
}
}, 100));
At the moment I don't know why append is not working but with a little workaround you can obtain what you want. Concatenate the original text and the actual one and use text() to set it again:
var init = true;
$('#btn').on('click', function() {
$('#text').text(init);
setTimeout(myDelay, 5000);
});
function myDelay() {
let originalText = $('#text').text();
init = false;
console.log("init is false");
console.log("original text displayed: " + originalText);
$('#text').text(originalText + " " + init);
}
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<button id='btn'> TRIGGER </button>
<div id="text"></div>

global variables in js, how to avoid them

I have a change() function that uses a setInterval() to repeat an animation:
function change(){
interval = setInterval(c,300);
function c(){...}
c()
}
The c() function does the work.
I also have a stop() function that stops all the animation and restore the initial situation:
function stop(){
clearInterval(interval);
...
};
I've read that is better use the var keyword instead declaring a global variable. But I cannot get access from the stop() function to interval if I do so. Declaring interval outside the change() function also gives me a problem.
ok i'm trying the last solution proposed by Ben Aston. Here the code:
function Animator() {
var id;
return {
start: start,
stop: stop,
};
function start() {
id = requestAnimationFrame(go);
}
function stop() {
clearAnimationFrame(id);
}
function go() {
// increment the animation
for (var i=0;i<img.length;i++){
var num = randNum(0,img.length-1)
var btn = img[i].nextSibling.nextSibling.childNodes[1]
img[i].setAttribute("src",img_path[num].path);
$(btn).css({"background-color":img_path[num].color,"border":"4px solid"+img_path[num].color});
$(img[i]).animate({width: "-=80px", height: "-=80px"},'slow');
$(img[i]).animate({width: "+=80px", height: "+=80px"},'slow')}
id = requestAnimationFrame(go)
}
}
basically when the user press a button, the images start to change their width and height and their color.
this is the rest:
var animator = new Animator();
function stop(){ //fn related to the stop button
animator.stop()};
function change(){ //fn related to the start button
animator.start()}
I dont know how to use requestAnimationFrame properly, i'm studying it right now. but when i press the start button the images change just one time and then they stopped.
In the previous code i had a for loop that did the work:
function change(){
interval = setInterval(c,300);
function c(){
for (var i=0;i<img.length;i++){
var num = randNum(0,img.length-1)
var btn = img[i].nextSibling.nextSibling.childNodes[1]
img[i].setAttribute("src",img_path[num].path);
$(btn).css({"background-color":img_path[num].color,"border":"4px solid"+img_path[num].color});
$(img[i]).animate({width: "-=80px", height: "-=80px"},'slow');
$(img[i]).animate({width: "+=80px", height: "+=80px"},'slow')}}
c()}
I admit that i dont have quite clear how to implement the go func?
thanks
edit: now it works (i was working with another file :)) but i have problem with the stop button
You can use Closure as well, read the documentation here :
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
With Closure you can define private and public function.
In raw JavaScript you could do the following:
Using ES5:
function Animator() {
var id;
return {
start: start,
stop: stop,
};
function start() {
id = requestAnimationFrame(go);
}
function stop() {
clearAnimationFrame(id);
}
function go() {
// increment the animation...
if(shouldContinue()) { // you define `shouldContinue`
id = requestAnimationFrame(go);
}
}
}
var animator = new Animator();
animator.start();
// ...
animator.stop()
hi using closures and with set interval things works properly:
var Button_Obj = function(){
var intervalID;
function start(){
return intervalID = setInterval(change,300) //change is the function that do the animation with a loop, i keep it private
};
function stop(){
clearInterval(intervalID)
};
return {start : start, stop : stop}
now in the global space i have only:
var btn_trigger = new Button_Obj();
and in the button tag i put:
<button style="border:1px solid #9dbbe4;" class="change-button" id="change-order" onclick="btn_trigger.start()" type="button">Start Moving</button>
now the global space is more clean, this implmentation works, with RequestAnimationFrame i have some problem, but i will try with it as well later

disable function using javascript

I can not seem to find the code to disable a javascript function. What I want to do is have a javascript function and then I want to disable it. Here is the code:
<script>
var fooFunc = function fooFunction() {
alert("HELLO");
};
$(document).ready(function() {
fooFunc.disable();
});
</script>
<button onclick="fooFunc()">Button</button>
Basically, when the button is click the function should not work, it should be disabled. Thanks
"Disabling" fooFunc is the same as setting it to an empty function (not to null--that will cause an error when it is called the next time). In this case:
$(document).ready(function() {
fooFunc = function() { };
});
But I don't see how this is different from simply removing the onclick handler from the HTML element.
If you want the ability to disable/re-enable the function, you can write it like this:
fooFunc = function() {
function _fooFunc() {
if (!enabled) return;
alert("HELLO");
}
var enabled = true;
_fooFunc.enable = function() { enabled = true; };
_fooFunc.disable = function() { enabled = false; };
return _fooFunc;
}();
If you want to extend this to allow any function to be enabled/disabled, you can write a higher-order function, which takes any function as a parameter, and returns a function with enable and disable methods attached to it:
function disablable(fn) {
function inner() {
if (!enabled) return;
fn();
}
var enabled = true;
inner.enable = function() { enabled = true; };
inner.disable = function() { enabled = false; };
return inner;
}
Now you can define fooFunc as
var fooFunc = disablable(function fooFunction() {
alert("HELLO");
});
and the rest of your code will work as you want.
You can access the onclick property of the element..
<button id="id" onclick="fooFunc()">Button</button>
<script>
document.querySelector('#id').onclick = '';
</script>
If you don't want the function to work at all and be totally disabled then use the below.
If you want the function to work only under certain conditions then you will need if/else statements so it will work only when the conditions that you have set are met.
$(document).ready(function(){
$("button").onclick(function(event){
event.preventDefault();
});
});
You were going to define it back to undefined or null.
fooFunc=undefined;
You Should be doing this :) Change function definition on very first run and you are good to go.
<! DOCTYPE html>
<html lang="en">
<body>
<script>
var fooFunc = function() {
alert("HELLO");
fooFunc = function(){};
};
var enablefooFunc = function()
{
fooFunc = function() {
alert("HELLO");
fooFunc = function(){};
};
}
</script>
<button onclick="fooFunc()">Run once and Disable FooFunc</button>
<button onclick="enablefooFunc()">Enable FooFunc</button>
</body>
</html>

How does setInterval() work with button.onclick

I want the alertMe function to be called only when the button is clicked, but it gets called (the setInterval gets called which calls that) AS SOON AS THE PAGE LOADS. But if I take the pageLoad function away, then startButton is null and I can't do anything with it.Thanks in advance, guys!
/when user clicks start, start the animation
window.onload = pageLoad;
function pageLoad() {
var startButton = document.getElementById("start");
startButton.onclick = setInterval(alertMe,200);
}
function alertMe() {
alert("hi");
}
function pageLoad() {
var startButton = document.getElementById("start");
startButton.onclick = alertMe;
}
function alertMe() {
setInterval(function(){
alert("hi");
},200);
}
Move your interval inside the alertMe function, and pass that as a reference to startButton.onclick
DEMO: http://jsfiddle.net/gHS4a/
basically you need to do it like this:
startButton.onclick = function() {
interval = setInterval(alertMe, 200);
}
what it does is it sends reference to the alertMe function
another way would be:
startButton.onclick = function() {
interval = setInterval(function(){
alertMe();
}, 200);
}
which would send a reference to an anonymous function which will call the alertMe function

Categories

Resources