One HTML button to invoke 3 functions consecutively - javascript

I am new to Javascript programming, and need some help.
I have one HTML button, and I want to invoke 3 functions.
The first time I click the button, I want to invoke function 1.
The next time I click the button, I want to invoke function 2.
The third time I click the button, I want to invoke function 3.
I was thinking that I could use if tests.
i++ when button is clicked,
if ( i == 1){ function1(); } .....
HTML
<button type="button" onclick="myFunction()">Hei</button>
Javascript
if(i == 1){
test1();
}
if(i == 2){
test2();
}
if(i == 3){
test3();
}
function test1() {
document.getElementById("print1").innerHTML = "test1";
}
function test2() {
document.getElementById("print2").innerHTML = "test2";
}
function test3() {
document.getElementById("print3").innerHTML = "test3";
}
This is just for testing/practice, so the code has no point
But I think there has to be another way.

Try this:
<button onclick="myFun(i)"></button>
in javascript,
function myFun(i) {
(i===0 && function1()) || (i===1 && function2()) || function3();
}

//Html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<button onclick="triggerFunc()">Click Me</button>
</body>
</html>
//Javascript
var obj = {
f1: function() {
alert('from f1');
},
f2: function() {
alert('from f2');
},
f3: function() {
alert('from f3');
}
};
window.flag = 1;
function triggerFunc() {
var flag = window.flag + 1;
if(flag > 3){
flag = 1;
}
window.flag = flag;
obj['f'+ flag]();
}
just check the jsbin link http://jsbin.com/dudubaxafu/edit?html,js,output

You can do like following code :-
HTML code :-
<button type="button" onclick="myFunction()">Hei</button>
javascript code :-
i = 1;
function myFunction()
{
if (i == 1)
{
i++;
test1();
}
else if (i == 2)
{
i++;
test2();
}
else if (i == 3)
{
i++;
test3();
}
}
function test1() {
document.getElementById("print1").innerHTML = "test1";
}
function test2() {
document.getElementById("print2").innerHTML = "test2";
}
function test3() {
document.getElementById("print3").innerHTML = "test3";
}
It may help you.

I would not recommend polluting the global namespace via window["i"], which limits you to only one such button.
I would use something like this:
function cycle(){
var i = 0;
var args = arguments;
return function(){
args[i]();
i++;
if(i>=args.length)
i = 0;
}
};
then you can use it like so:
document.getElementById("button1").addEventListener("click", cycle(
function(){
alert(1);
},
function(){
alert(2);
},
function(){
alert(3);
}));
Here's a fiddle sample:
https://jsfiddle.net/h6qsam8e/

Related

Javascript if - else if inside switch using ("#id").length

Code edited. Apologizes for the incomplete first code
I've this code that takes input from the user, and it appends an image that matches that input. What I want to do is to set different buttons (200 aprox.) to append a different image if other button is pressed. The approaching I'm doing for this is to target the first if, within the first switch case, with the ("#id").length condition.
This is a short example of my code:
HTML:
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://code.jquery.com/jquery-3.1.1.js"></script>
</head>
<body>
<section id="section">
<input id="input">
<button id="1"></button>
<button id="2"></button>
</section>
<div id="div"></div>
</body>
</html>
Javascript:
$(document).ready(function() {
var str;
$("#1, #2").click(function () { test(); });
});
var input = ['a','b','c'];
function test() {
var interval = setInterval(match, 1);
$("div").html("");
str = $("input").val().toLowerCase();
var i = 0;
function match() {
var imgs = ["<img src='https://1.bp.blogspot.com/-v2N2hPY33pc/V488gHu5aWI/AAAAAAAAHFM/loGVDK5OlGcft5UUz8-AHZjAd3E7OlZjACLcB/s1600/colorful-background-with-waves.jpg' alt='0'>",
"<img src='https://upload.wikimedia.org/wikipedia/commons/c/c8/Widget_icon.png' alt='1'>"];
if (i < str.length) {
switch (str[i]) {
case input[0]:
if ($("#1").length){
$("div").append(imgs[0]);
i++;
break;
}else if ($("#2").length){
$("div").append(imgs[1]);
i++;
break;
}
}
else {
clearInterval(interval);
$("input").val("");
}
}
}
Now, I've managed to make the if work, it shows the image, but if I press the second button, the else-if never works. What am I doing wrong?
Well I can't for the life of me figure out what you're trying to do with this code, but here is a working version of it...
$(document).ready(function() {
var str;
$("#1, #2").click(function () { test(this); });
});
var input = ['a','b','c'];
function test(caller) {
var interval = setInterval(match, 1);
var i = 0;
$("div").html("");
str = $("input").val().toLowerCase();
function match() {
var imgs = ["<img src='https://1.bp.blogspot.com/-v2N2hPY33pc/V488gHu5aWI/AAAAAAAAHFM/loGVDK5OlGcft5UUz8-AHZjAd3E7OlZjACLcB/s1600/colorful-background-with-waves.jpg' alt='0'>","<img src='https://upload.wikimedia.org/wikipedia/commons/c/c8/Widget_icon.png' alt='1'>","<img src='https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/100px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg' alt='2'/>","<img src='https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Corythucha_ciliata.jpg/120px-Corythucha_ciliata.jpg' alt='3'/>"];
if (i < str.length) {
switch (str[i]) {
case input[0]:
if (caller.id == "1") {
$("div").append(imgs[0]);
i++;
break;
} else if (caller.id == "2") {
$("div").append(imgs[1]);
i++;
break;
}
case input[1]:
if (caller.id == "1") {
$("div").append(imgs[2]);
i++;
break;
} else if (caller.id == "2") {
$("div").append(imgs[3]);
i++;
break;
}
}
} else {
clearInterval(interval);
$("input").val("");
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="input"/>
<button id="1">1</button>
<button id="2">2</button>
<div></div>

How to exit a javascript function inside itself after an "if"?

I´m creating a game and I've got stuck with a counter in a function.
I want the function to loop five times and then if my element "nocolnum" has a value of 5, i need the function to exit or break.
here is my html:
<!DOCTYPE html>
<html>
<head>
<title>title</title>
</head>
<body>
<span id="opt1"></span>
<span id="nocolnum">0</span>
</body>
</html>
here is my js:
function func(num) {
num = num + 1;
var opt = document.getElementById('opt1');
opt.innerHTML= num + "%" ;
var move = setTimeout("func("+num+")",15);
var nocolnum = document.getElementById('nocolnum');
if(num == 100){
nocolnum.innerHTML++;
clearTimeout(move);
}
if (nocolnum == 5) {
// I dont know what to put here
// to break out
// a break, return or something??
}
var one = 0;
func(one);
}
if (nocolnum == 5) {
// I dont know what to put here
// to break out
// a break, return or something??
return false;
}
If you want to break function you can simlpy return
if (nocolnum == 5) {
return true;
}
or
if (nocolnum == 5) {
return false;
}

Clearing an interval

I'm studying Javascript and I'm having difficulties and understanding why a piece of code (see below) I edited doesn't work. The purpose is pretty simple - I want to create a button that stops and runs time back again. I even printed text to be sure my code enters the 'if' and 'else' statements, but the clearInterval doesn't seem to work. Help much appreciated!
(*the original code belongs to w3schools, I have added the "loop function" just to see if it would work, and it doesn't ;( )
This is the code:
<!DOCTYPE html>
<html>
<body>
<p>A script on this page starts this clock:</p>
<p id="demo"></p>
<button onclick="checkTime()">Stop time/Start time again</button>
<p id="test"></p>
<script>
var myCounter = 0;
var myVar = setInterval(myTimer ,1000);
function myTimer() {
var d = new Date();
document.getElementById("demo").innerHTML = d.toLocaleTimeString();
}
function checkTime() {
myCounter += 1;
if (myCounter == 1) {
clearInterval(myVar);
document.getElementById("test").innerHTML = "ok";
} else {
var myVar = setInterval(myTimer ,1000);
myCounter = 0;
document.getElementById("test").innerHTML = "clicked again";
}
}
</script>
</body>
</html>
Thanks!
Remove the var from the second var myVar = setInterval...
The second one is scoped to your function and "overrides" the first one...
function checkTime() {
myCounter += 1;
if (myCounter == 1) {
clearInterval(myVar);
document.getElementById("test").innerHTML = "ok";
} else {
myVar = setInterval(myTimer ,1000);
myCounter = 0;
document.getElementById("test").innerHTML = "clicked again";
}
}
Just glanced at your code quickly, but I notice that you are redeclaring your myVar variable, which is the variable that is being cleared when you call clearInterval due to a funky feature in javascript called hoisting.
Try the following...
<script>
var myCounter = 0;
var myVar = setInterval(myTimer ,1000);
function myTimer() {
var d = new Date();
document.getElementById("demo").innerHTML = d.toLocaleTimeString();
}
function checkTime() {
myCounter += 1;
if (myCounter == 1) {
clearInterval(myVar);
document.getElementById("test").innerHTML = "ok";
} else {
myVar = setInterval(myTimer ,1000);
myCounter = 0;
document.getElementById("test").innerHTML = "clicked again";
}
}
</script>

jQuery/JavaScript: Initiate and terminate a loop with the same button

I want to build a button that when I click it, the function in JavaScript associated with it initiates (so a loop inside it start doing something).
If I click it again before the loop inside the function finishes, the loop will terminates.
If I click it again after the loop inside the function has already finished, the loop will just start as usual.
How do I do this with the following code?
Thanks in advance.
HTML:
<button id="startstop" class="btn btn-primary" onclick="count()">
JavaScript:
function count() {
var val = 0;
var loop = setInterval(function(){
val++;
if (val > 1000} {
clearInterval(loop);
}
}, 100);
}
try this code
var loop;
function count() {
var val = 0;
if (loop) {
clearInterval(loop);
loop = null;
}
else{
loop = setInterval(function(){
val++;
console.log(val);
if (val > 1000) {
clearInterval(loop);
loop = null;
}
}, 100);
}
}
I'm not a big fan of doing work for people, but on this occasion I'll succumb...
You need to store the internal ID outside of the function, and base your process on that. If the ID is not set, start the interval, if it is set stop the interval.
Note, that I've massively reduced the length of interval, and the number of times it fires for this example...
var _intervalId = -1;
function count() {
if (_intervalId == -1) {
var val = 0;
_intervalId = setInterval(function(){
val++;
if (val > 200) {
clearInterval(_intervalId);
_intervalId = -1
document.getElementById("output").innerHTML = "stopped automatically";
}
}, 10);
document.getElementById("output").innerHTML = "started";
} else {
clearInterval(_intervalId);
_intervalId = -1;
document.getElementById("output").innerHTML = "stopped manually";
}
}
<button onclick="count();return false">Click Here</button>
<div id="output"></div>
Place loop variable in global scope and everytime the user clicked stop previous loop if it's already started if not start it.
Hope this helps.
var loop=null;
count = function () {
var val = 0;
//Stop previous loop if it's already started
if(loop!=null){
clearInterval(loop);
loop=null;
}else{
loop = setInterval(function(){
val++;
console.log(val);
$('span').text(val);
if (val >= 20) {
clearInterval(loop);
}
}, 100);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="startstop" class="btn btn-primary" onclick="count()">Count</button>
<span>0</span>
I had fun building a small class for this. Feel free to use.
// Counter class
function Counter(callback, speed, max, init){
var loop = null;
this.callback = callback;
this.value = init || 0;
this.max = max;
function count(){
if (this.max && this.value >= this.max) {
clearInterval(loop);
loop = null;
} else {
this.value++;
}
this.callback(this.value);
}
this.start = function(){
if(!this.isStarted){
loop = setInterval(count.bind(this), speed);
}
};
this.stop = function(){
if(this.isStarted){
clearInterval(loop);
loop = null;
}
}
Object.defineProperty(this, "isStarted", { get: function(){
return !!loop;
}});
}
// Usage example.
var result = document.getElementById("counter");
var button = document.getElementById("startstop");
// Create the counter and the callback.
var counter = new Counter(function(val){
result.innerHTML = val;
}, 100, 1000);
// Init the result value.
result.innerHTML = counter.value;
// Listen for click events on the button.
button.addEventListener("click", function(){
if(counter.isStarted){
counter.stop();
} else {
counter.start();
}
});
<div id="counter"></div>
<button id="startstop">Toggle</button>

Need Help In Javascript Text Typer Effect

I have a javascript text typer code:
CSS:
body
{
background-color:black;
}
#writer
{
font-family:Courier;
font-size:12px;
color:#24FF00;
background-color:black;
}
Javascript:
var text = "Help Please, i want help.";
var counter = 0;
var speed = 25;
function type()
{
lastText = document.getElementById("writer").innerHTML;
lastText+=text.charAt(counter);
counter++;
document.getElementById("writer").innerHTML = lastText;
}
setInterval(function(){type()},speed);
HTML:
<div id="writer"></div>
I want to know how can i use <br> tag (skipping a line or moving to another line). I tried many ways but failed, I want that if I Typed My name is Master M1nd. and then i want to go on the other line how would i go?
I've made a jQuery plugin, hope this will make things easier for you. Here is a live demo : http://jsfiddle.net/wared/V7Tv6/. As you can see, jQuery is loaded thanks to the first <script> tag. You can then do the same for the other <script> tags if you like, this is not necessary but considered as a good practice. Just put the code inside each tag into separate files, then set appropriate src attributes in the following order :
<script src=".../jquery.min.js"></script>
<script src=".../jquery.marquee.js"></script>
<script src=".../init.js"></script>
⚠ Only tested with Chrome ⚠
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
jQuery.fn.marquee = function ($) {
function findTextNodes(node) {
var result = [],
i = 0,
child;
while (child = node.childNodes[i++]) {
if (child.nodeType === 3) {
result.push(child);
} else {
result = result.concat(
findTextNodes(child)
);
}
}
return result;
}
function write(node, text, fn) {
var i = 0;
setTimeout(function () {
node.nodeValue += text[i++];
if (i < text.length) {
setTimeout(arguments.callee, 50);
} else {
fn();
}
}, 50);
}
return function (html) {
var fragment, textNodes, text;
fragment = $('<div>' + html + '</div>');
textNodes = findTextNodes(fragment[0]);
text = $.map(textNodes, function (node) {
var text = node.nodeValue;
node.nodeValue = '';
return text;
});
this.each(function () {
var clone = fragment.clone(),
textNodes = findTextNodes(clone[0]),
i = 0;
$(this).append(clone.contents());
(function next(node) {
if (node = textNodes[i]) {
write(node, text[i++], next);
}
})();
});
return this;
};
}(jQuery);
</script>
<script>
jQuery(function init($) {
var html = 'A <i>marquee</i> which handles <u><b>HTML</b></u>,<br/> only tested with Chrome. Replay';
$('p').marquee(html);
$('a').click(function (e) {
e.preventDefault();
$('p').empty();
$('a').off('click');
init($);
});
});
</script>
<p></p>
<p></p>
Instead of passing <br> char by char, you can put a \n and transform it to <br> when you modify the innerHTML.
For example (http://jsfiddle.net/qZ4u9/1/):
function escape(c) {
return (c === '\n') ? '<br>':c;
}
function writer(text, out) {
var current = 0;
return function () {
if (current < text.length) {
out.innerHTML += escape(text.charAt(current++));
}
return current < text.length;
};
}
var typeNext = writer('Hello\nWorld!', document.getElementById('writer'));
function type() {
if (typeNext()) setInterval(type, 500);
}
setInterval(type, 500);
Also probably you'll be interested in exploring requestAnimationFrame (http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/), for your typing animation :)

Categories