Javascript function being executed even if its not called - javascript

Hi so I'm fairly new to javascript and right now, I'm experimenting in defining functions and hiding/showing specific elements.
in this simple program that I made, I am trying to show a loading screen while a function is still executing. the problem is, the function that is inside the onlick event handler executes even without clicking the button
<body>
<button id="thisbutton" type="button">clickme</button>
<div>
<p> The download will begin in <span id="countdowntimer">10 </span> Seconds</p>
</div>
<div id="loadss" class="LockOn"></div>
<script>
document.getElementById("thisbutton").onclick(meow());
document.onload = rawr();
function rawr() {
document.getElementById("loadss").style.visibility = "hidden";
document.getElementById("loadss").style.display = "none";
}
function meow() {
document.getElementById("loadss").style.visibility = "visible";
document.getElementById("loadss").style.display = "block";
time();
document.getElementById("loadss").style.visibility = "hidden";
document.getElementById("loadss").style.display = "none";
};
function time() {
var timeleft = 10;
var downloadTimer = setInterval(function () {
timeleft--;
document.getElementById("countdowntimer").textContent = timeleft;
if (timeleft <= 0)
clearInterval(downloadTimer);
}, 1000);
}
</script>

In Javascript, functions are first-class citizens. This means you can treat them like most variables:
function test () { console.log('Hi!'); }
var x = test;
And you can execute them by using parentheses on any reference to them:
test(); // will execute function test
x(); // will _also_ execute function test
Hence, your code:
document.getElementById("thisbutton").onclick(meow());
document.onload = rawr();
is executing the functions meow and rawr. You perhaps want to pass references to these functions:
document.getElementById("thisbutton").onclick(meow);
document.onload = rawr;

your code
document.getElementById("thisbutton").onclick(meow());
should be like following
document.getElementById("thisbutton").onclick = meow;
notice i did not call the meow function and onclick is not a function but a property.
also your code
document.onload = rawr;
should be
document.onload = rawr;
when you use parentheses then the function gets called.

Related

How to stop an onended function onclick

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

addEventListener null, onclick works (onload did not work and js is in separate document)

I can use onClick in my HTML file to call upon functions created in my JavaScript file, however, attempting to use addEventListener does not work and I am not sure why. Error in console.log says that the addEventListner is null.
I am attempting to change the display of my web page via a click event.
I understand that addEventListener does not cancel out the previous event called, but even the first event called in my code does not trigger the change which is confusing.
After looking this up I tried the following:
Using window.onload = function(){} and placing the below code within the function.
document.getElementById('begin_game').addEventListener('click', beginGame);
document.getElementById('select_category').addEventListener('click', selectCategory);
Using this code independent of the window.onload function but the addEventListener still returned as null.
The beginGame and selectCategory functions reference the following code in the js file:
function Hide(x) {
const hidden = document.getElementsByClassName(x);
for (var i=0, length= hidden.length; i < length; i++) {
if ( hidden[i].style.display != 'none') {
hidden[i].style.display = 'none';
}
}
}
function Display(x) {
const show = document.getElementsByClassName(x);
for (var i = 0, length = show.length; i < length; i++) {
if (show[i].style.display != 'flex') {
show[i].style.display = 'flex';
}
}
}
//Below is how the functions are referenced
function beginGame() {
document.getElementById('welcome').style.display = 'flex';
Hide('start');
}
function selectCategory () {
Hide('welcome-content');
Display('category');
}
// Where I would place the event listeners I mentioned above
// document.getElementById('begin_game').addEventListener('click', beginGame);
// document.getElementById('select_category').addEventListener('click', selectCategory);
// When I used the window.onload function, I placed it at the bottom of the js page
Buttons from HTML file
<button type='submit' class='welcome-content' id='select_category'>
Categories
</button>
</div>
<h1 class= 'start'>
Math Maniacs
</h1>
<button type='submit' class='start' id='begin_button'>
START
</button>
Using window.onload was the correct solution, I realized that I was not enveloping all of the relevant js code with the onload function.
Before I did this
window.onload = function() {
document.getElementById('begin_game').addEventListener('click', beginGame);
document.getElementById('select_category').addEventListener('click', selectCategory);
}
However, I believe that didn't work because I did not place the functions the event listeners were referencing into the window.onload function.
Once I wrote the below
window.onload = function() {
function beginGame() {
document.getElementById('welcome').style.display = 'flex';
Hide('start');
}
document.getElementById('begin_button').addEventListener('click', beginGame);
function selectCategory() = {
Hide('welcome-content');
Display('category');
}
document.getElementById('select_category').addEventListener('click', selectCategory);
}
The code worked as intended

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

Implement press and hold on a button

Thank you for the previous (deleted by moderator) explanation and the simple implementation but it does not work out for me. The 'holdit' function works but it is not is not steady probably because there is an 'onmouseup' in the 'holdit' function too, Even if I disable the onmouseup at the HTML button it's not very steady. Maybe it's better to use an addEventListener- onmousedown-interval function but again I don't know how to implement it in the simplest possible way. Here's the complete function that shows a pressed button and increases the timeSeconds var by one. For safety the var. number is within a limit.
Please help.
HTML:
<img id="but4" class="button" src= "//:0" onmousedown="timesecPlus();"onmouseup="timesecPlsUp();"/>
JAVASCRIPT:
function timesecPlus() {
var pmknop = document.getElementById('but5');
pmknop.src = secminBtndwn; //inline Base64 data: button image down (pressed)
timeSeconds = ((timeSeconds>wedstrijdperiode.seconden-6)?(timeSeconds):(++timeSeconds)); //You can ++ chase-back the timeseconds until 5 sec's from period start-time
displayTime( timeSeconds );
};
function timesecPlsUp() {
var pmknop = document.getElementById('but5');
pmknop.src = secminBtn; //inline Base64 data: button image up (normal)
};
// Things I tried:
//holdit(pmknop, function () { ++timeSeconds ; displayTime( timeSeconds );}, 2000, 2);
//pmknop = pmknop.addEventListener('mousedown', function() { interval = setInterval(timesecPlus (), 2000); });
function holdit(btn, action, start, speedup) {
var t;
var repeat = function () {
action();
t = setTimeout(repeat, start);
start = start / speedup;
}
btn.onmousedown = function() {
repeat();
}
btn.onmouseup = function () {
clearTimeout(t);
}
};
The holdit function is taking four variables. The first: btn, is the button id. This is used to determine the action performed whenever the mouse is clicked.
The second variable is a reference to a function. Its called a callback function, since you will be passing a function that will be Caaalleed whenever you call holdit.
The last two variables simply determine when and how long to delay the execution of the repetition and and by how much each repetition will speed up by.
var repeat = function () {
action();
t = setTimeout(repeat, start);
start = start / speedup;
}
Repeat is a recursive function that will be called after 'start' number of milliseconds and be repeated more frequently after each iteration.
Simple implementation:
var btn = document.getElementsByClassName('button')[0];
holdit(btn, function () { timeSeconds++ ; displayTime( timeSeconds );}, 1000, 2);
Implementation without holdit:
var btn = document.getElementsByClassName('button')[0];
var couterFunc, couter=0;
btn.addEventListener('mousedown',function(){couterFunc = setInterval(update,1000); update()})
btn.addEventListener('mouseup',function(){clearInterval(couterFunc)})
/* function that will fire when button press*/
function update(){console.log(++couter)};

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