one button calls two different functions on different clicks - javascript

<script>
function one() {
blah blah blah
}
function two() {
blah blah blah
}
</script>
<button onclick="one(); two()">Click Me</button>
This will call the two functions at the same time. What I want is to call function one() on the first click and then call function two() on the second click. Calls function three() on 3rd click and so on until 7th click
I would prefer to not use jQuery if possible

You can use an IIFE to accomplish this:
var fn3 = (function() {
var first = true;
return function() {
first ? fn1() : fn2();
first = !first;
}
})();
function fn1() {
console.log(1);
};
function fn2() {
console.log(2);
};
<button onClick="fn3()">click</button>

The solution is not too complex, you can just one() and two() from another function.
var callOne = true;
function one() {
alert('Call one');
}
function two() {
alert('Call two');
}
function call(){
if(callOne) one();
else two();
callOne = !callOne;
}
<button onclick="call();">Click Me</button>

One simple way of doing this is to reassign the onclick value:
<button id="clickme">Click Me</button>
<script>
function one() {
alert('one clicked');
document.getElementById('clickme').onclick = two;
}
function two() {
alert('two clicked');
}
document.getElementById('clickme').onclick = one;
</script>
Using this trick you have the option to disable the button after calling two():
document.getElementById('clickme').onclick = null;
Toggle the click handler back to one():
document.getElementById('clickme').onclick = one;
Or do anything else you want.

I'll do it like bellow
On click of the button have a function which decides which function to call according to number of times.
<button onclick="decideFunction()">Click Me</button>
var times = 0;
var one = function(){
alert('first time');
}
var two = function(){
alert('After first');
}
var decideFunction = function(){
if(times == 0){
one();
times++;
}
else{
two();
}
}
So first time it will execute function one and second time onwards it will execute function two.

The simplest way is defining an extra variable to false(or true, of course). While our variable is false, clicking button calls first function and changes the variable to true. On second click, our onclick function checkes the variable value and calls the function which we defined for true value.
var button = document.getElementById('button');
var x = false;
button.addEventListener('click', function(){
if(!x){
alert('function 1');
x = true;
}else{
alert('function 2');
x = false;
}
})

Related

Vanilla Javascript how override added function on event listener?

I have a bootstrap modal that has some custom events, like hidden.bs.modal, depending on where the user does, I want the function in this event to be replaced, maybe it's better to understand with a simple example, consider:
const currentModal; // imagine an any modal here.
window.addEventListener('load', () => {
currentModal.addEventListener('hidden.bs.modal', standardFunction );
});
function standardFunction(){
alert('hi there');
// this is standard output to modal closed
}
function buttonClickedChange(){
// Here, i need override standardFunction
this.standardFunction = function(){
alert('modal event hidden.bs.modal changed with success!');
// this must be override previous output
};
}
What happens is that regardless of the redeclaration of the function, the output for the method is still standard, this is because the eventlistener does not refer to the stored function but only "copy" its content and creates its scope only inside.
The problem you have is when you bind the event, you are referencing that function. When you replace it does not update the reference to that function. You can clearly see that this will not work with the example
var btn = document.querySelector("button");
function myFunc () {
console.log(1);
}
btn.addEventListener("click", myFunc);
myFunc = function() {
console.log(2);
}
<button>Click Will Show 1</button>
Just remove the event listener and bind a new event.
currentModal.removeEventListener('hidden.bs.modal', standardFunction );
currentModal.addEventListener('hidden.bs.modal', myUpdatedFunction );
function myFunc () {
console.log(1);
}
var btn = document.querySelector("button");
btn.addEventListener("click", myFunc);
function myFunc2() {
console.log(2);
}
btn.removeEventListener("click", myFunc);
btn.addEventListener("click", myFunc2);
<button>Click</button>
If for some reason you can not remove the event, the only way around it would not to bind directly to the function, but to have another function call that function.
var btn = document.querySelector("button");
var myFunc = function() {
console.log(1);
}
function clickFunction () {
myFunc();
}
btn.addEventListener("click", clickFunction);
myFunc = function() {
console.log(2);
}
<button>Click</button>
Or how most people would do it is to add the logic into the function on what to do
var btn = document.querySelector("button");
var state = 0;
var myFunc = function() {
if (state===0) {
console.log(1);
} else {
console.log(2);
}
}
state = 1;
btn.addEventListener("click", myFunc);
<button>Click</button>
You used function expressin instead of function declaration. When you use function yourFunction it is moved to the top with all of the other declared functions. When you use var yourFunction = function () it is right there where you declared it. This means that hidden.bs.modal is searching for the top most function with that name which in this case is the first one you declared or the standard one. One of the ways is that you can declare your function in the global scope: function standardFunctionOverride() and add that to the listener.

how to make a button call different function every-time it's clicked?

How do I make a button call different function every time it's clicked?
<button id="OpenGoogle">
Open Google, facebook, instagram
</button>
I have 3 functions and I want call them with the same button, like that:
1st click calls func1(),
2nd click calls func2(),
3rd click calls func3(),
function func1(){
window.open("https://www.gmail.com");
}
function func2(){
window.open("https://www.facebook.com");
}
function func3(){
window.open("https://www.instagram.com");
}
function func1(){
console.log("goo");
}
function func2(){
console.log("fac");
}
function func3(){
console.log("insta");
}
const btn = document.querySelector("#OpenGoogle");
funcs = [func1, func2, func3];
let i = 0;
btn.addEventListener("click", e => {
funcs[i]();
i++;
if (i >= funcs.length) i = 0;
});
<button id="OpenGoogle">
Open Google, facebook, instagram
</button>
Store all the functions inside an array and keep track of the index.
function func1(){
console.log("https://www.gmail.com");
}
function func2(){
console.log("https://www.facebook.com");
}
function func3(){
console.log("https://www.instagram.com");
}
const btn = document.querySelector("#OpenGoogle");
const callbacks = [func1, func2, func3];
let idx = 0;
btn.addEventListener("click", e=>{
callbacks[idx]();
if(idx + 1 < callbacks.length) idx++;
});
<button id="OpenGoogle">
Open Google, facebook, instagram
</button>
I don't think you can do this directly. But you can do by it maintaining the last executed function in your js.
Create one main function using this function call the desire functions
var lastExeFun = 3;
function funcMain() {
switch (lastExeFun) {
case 1:
func2();
break;
case 2:
func3();
break;
case 3:
func1();
break;
}
lastExeFun = lastExeFun >= 3 ? 1 : (lastExeFun + 1)
}
function func1(){
// window.open("https://www.gmail.com");
console.log('func1');
}
function func2(){
// window.open("https://www.facebook.com");
console.log('func2');
}
function func3(){
// window.open("https://www.instagram.com");
console.log('func3');
}
<button onClick="funcMain()">Click Me</button>
Just use an array with usefull information
// guess who..
const buttonOpens = document.getElementById('OpenOne')
// adding button infos
buttonOpens.toOpen =
[ { lib:'Open <b>Google</b>, facebook, instagram', url:'https://www.gmail.com' }
, { lib:'Open Google, <b>facebook</b>, instagram', url:'https://www.facebook.com' }
, { lib:'Open Google, facebook, <b>instagram</b>', url:'https://www.instagram.com' }
]
buttonOpens.activ = 0
// initialize
buttonOpens.innerHTML = buttonOpens.toOpen[buttonOpens.activ].lib
buttonOpens.onclick =()=>
{
console.clear()
console.log( buttonOpens.toOpen[buttonOpens.activ].url )
// window.open(buttonOpens.toOpen[buttonOpens.activ].url)
//set the next ( circular )
buttonOpens.activ = ++buttonOpens.activ % buttonOpens.toOpen.length
buttonOpens.innerHTML = buttonOpens.toOpen[buttonOpens.activ].lib
}
<button id="OpenOne"> Open One?</button>

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>

block function execution during setTimeout

I have a function that I call when I press a button. My goal is to print "hello" in the console after 5 seconds and, if I press the button during the 5 seconds of waiting, nothing at all.
The problem is that, if I press the button while i'm waiting the 5 seconds, in the console I still get more than one "hello". What am I doing wrong?
Here is the Javascript code:
function foo(){
var block = false;
if(!block){
block = true;
myVar = setTimeout(checkAgain, 5000);
}
function checkAgain(){
console.log("hello");
block = false;
}
}
And the HTML:
<button id="button" onClick="foo();">Click me!</button>
You don't need to manually handle the "block", you can just cancel the call with clearTimeout. This seems to be more natural for me - when you click once you say "call this function in 5 seconds", and when you click it again you say "don't call it".
var timeout = null;
var button = document.querySelector("#btn");
button.onclick = function()
{
if (timeout)
{
clearTimeout(timeout);
timeout = null;
}
else
{
timeout = setTimeout(function() {
timeout = null;
run();
}, 1000); // should be 5000, just for test
}
};
function run()
{
console.log("Hello world");
}
<input type="button" id="btn" value="Click me">
You're not doing anything to block subsequent calls. block is a local variable inside foo, so there's a different one for each call to foo.
Instead, you have to have block outside foo:
var myVar;
var block = false;
function foo(){
if(!block){
block = true;
myVar = setTimeout(checkAgain, 5000);
}
function checkAgain(){
console.log("hello");
block = false;
}
}
document.getElementById("btn").addEventListener("click", foo);
<input type="button" id="btn" value="Click me">
That also means that checkAgain doesn't have to be recreated for every call to foo, since it doesn't need anything local to foo anymore:
var myVar;
var block = false;
function foo(){
if(!block){
block = true;
myVar = setTimeout(checkAgain, 5000);
}
}
function checkAgain(){
console.log("hello");
block = false;
}
document.getElementById("btn").addEventListener("click", foo);
<input type="button" id="btn" value="Click me">
(I assume all of this is in a scoping function or module so these aren't globals.)
That said, the button will remain active, giving the user the impression he/she could click it. Instead, you might consider making it possible for foo to disable and re-enable the button.
that is because you have defined variable 'block' in the scope of the function 'foo' and it is been initiated again every time you call the function. the correct implementation is:
var block = false;
function foo(){
if (!block) {
block = true;
myVar = setTimeout(checkAgain, 5000);
}
function checkAgain() {
console.log("hello");
block = false;
}
}

HTML, javascript Enable Disable Button

Overview: There is a Button on my webage, its a single button. When I click this button, it should call function X. If I click this button a second time, it should call function Y. Basically, this is an ON and OFF switch. this button calls a function via onclick="function X". the same onclick needs to call function Y if clicked again. I hope I made that clear.
It cannot be 2 seperate buttons. thats too easy. does anyone have any ideas ? the only flexibily I have in terms of languages is html, javacript and css. any ideas welcome.
You don't need multiple functions. Just use a boolean to toggle between 2 different parts of code.
var toggle = true;
function functionX(){
if(toggle){
// Logic for the first click
} else {
// Logic for the other click
}
toggle = !toggle; // change the toggle for the next time the button's clicked.
}
There are a few ways to do this:
Two Buttons
html
<button id="a" onclick="a()">Test</button>
<button id="b" onclick="b()" style="hidden">Test</button>
css
.hidden {
display: none;
}
js
function a() {
var buttonA = document.getElementById('a');
var buttonB = document.getElementById('b');
buttonA.classList.add('hidden');
buttonB.classList.remove('hidden');
}
function b() {
var buttonA = document.getElementById('a');
var buttonB = document.getElementById('b');
buttonB.classList.add('hidden');
buttonA.classList.remove('hidden');
}
Hold State in a var
html
<button onclick="x()">Test</button>
js
var clicked = 'b'; //initial state
function x() {
switch(clicked) {
case 'a':
clicked = 'a';
a();
break;
case 'b':
clicked = 'b';
b();
break;
default: throw 'unknown state';
}
}
function a() {
//something
}
function b() {
//something
}
Re-assign listener on click (Easier with jquery)
html
<button id="x">Test</button>
js
$(document).ready(function() {
$('#x').click(a());
});
function a() {
//do something then..
$('#x').click(b);
}
function b() {
//do something then..
$('#x').click(a);
}
try this code
var i = 0;
function fun() {
if (i == 0) {
funX();
i = 1;
} else {
funY();
i = 0;
}
}
function funX() {
console.log('x');
}
function funY() {
console.log('y');
}
<button id="test" onclick="fun()">Click</button>

Categories

Resources