Need help getting this closure working - javascript

I'd like to be able to call this function from another function and not use an event handler as in the code below. Instead of element.onclick, I'd like to do something like
window.myFunction = (function(){ //the rest of the closure code//}
where I can call myFunction(); from another function instead of having to click a button.
var element = document.getElementById('button');
element.onclick = (function() {
// init the count to 0
var count = 0;
return function(e) {
//count
count++;
if (count === 3) {
// do something every third time
alert("Third time's the charm!");
//reset counter
count = 0;
}
};
})();

LIVE DEMO
var element = document.querySelector('#button'),
count = 0;
function myCountFunction(){
count = ++count % 3; // loop count
if ( !count ) { // if count is 0
alert("Third time's the charm!");
}
}
//On click:
element.addEventListener('click', myCountFunction, false);
// Immediately:
myCountFunction(); // this will trigger the event once
// Inside some other function:
function myOtherFunction(){
myCountFunction();
}

This should work for you:
var element = document.getElementById('button');
var f = (function() {
var count = 0;
return function(e) { //e is not really needed, but left in there anyway
//count
count++;
if (count === 3) {
// do something every third time
alert("Third time's the charm!");
//reset counter
count = 0;
}
};
})();
element.onclick = f;
Fiddle: http://jsfiddle.net/2eFD2/2/

Related

Automatically Change Individual Table Data Using Javascript

I'm trying to mimic the look of a stock-exchange board, but can't seem to automatically change text without stopping another.
I've tried
var text = ["2.0%", "1.7%", "1.9%", "1.8%", "1.9%"];
var counter = 0;
var elem = document.getElementById("n1");
var inst = setInterval (change, 1000);
function change () {
elem.innerHTML = text[counter];
counter++;
var content = document.getElementById("n1");
if (counter >= text.length) {
counter = 0;
}
}
var text = ["-12.0%", "-13.7%", "-13.9%", "-12.8%", "-13.9%"];
var counter = 0;
var elem = document.getElementById("n2");
var inst = setInterval (change, 1000);
function change () {
elem.innerHTML = text[counter];
counter++;
var content = document.getElementById("n2");
if (counter >= text.length) {
counter = 0;
}
}
To no avail.
You can't have two different functions with the same name. One will override the other.
I created a single function that accomplishes your goals by passing in the target element and the data as arguments.
function change(elem, data) {
let counter = 0;
setInterval(function() {
elem.innerHTML = data[counter];
counter++;
if (counter >= data.length) {
counter = 0;
}
}, 1000);
}
change(document.getElementById("n1"), ["2.0%", "1.7%", "1.9%", "1.8%", "1.9%"]);
change(document.getElementById("n2"), ["12.0%", "2.7%", "3.9%", "4.8%", "5.9%"]);
<div id="n1"></div>
<div id="n2"></div>

How to Change innerHTML on Interval pulling from an array?

Trying to get an element to change every x number of seconds. When I click the button it should change the innerHTML, looping through an array. The code below changes the text but displays the last result in the array.
<h1 id="header">Agent</h1>
<button id="change-header" onclick="loopHeader()">Click Me</button>
<script>
function loopHeader() {
var loopHeader = setInterval(changeText, 1000);
}
function changeText() {
var headers = ["Agent", "Expert", "Homes", "Service", "Results"];
var text = "";
var i = 0;
var x = document.getElementById("header");
for (i = 0; i < headers.length; i++) {
text = headers[i];
x.innerHTML = text;
}
}
</script>
Move the count outside of the function, and then keep looping round and resetting to 0 when at end.
function loopHeader() {
var loopHeader = setInterval(changeText, 1000);
}
var headers = ["Agent", "Expert", "Homes", "Service", "Results"];
var loopItem = 0;
function changeText() {
loopItem++;
if (loopItem == headers.length) {
loopItem = 0;
}
document.getElementById("header").innerHTML = headers[loopItem];
}
</script>
<div id="header">
</div>
<button id="change-header" onclick="loopHeader()">Click Me</button>
That's because every time you changeText is called it start changing the innerHTML of the button by the text from the array all from index 0 to the end (It's happening you just can't see it because it's happening fast). What you need is to define i outside the function and every time the function is called increment i and show its corresponding value from the array without a loop. Like this:
<button id="change-header" onclick="loopHeader()">Click Me</button>
<script>
function loopHeader() {
// if you want to start the animation just after the button is clicked, then uncomment the next line
// changeText();
var loopHeader = setInterval(changeText, 1000);
}
var i = 0; // i declared outside with the initiale value of 0
var headers = ["Agent", "Expert", "Homes", "Service", "Results"]; // this also should be outside (what's the point of redefining it every time the function is called)
function changeText() {
var x = document.getElementById("change-header"); // the id is change-header
// increment i and check if its beyond the boundaries of the loop, or just use modulo operator t prevent it from going beyond
i = (i + 1) % headers.length;
x.textContent = headers[i]; // textContent is better than innerHTML
}
</script>

How can I use a default value for this array? The result is not displayed until the first loop

I have this code:
<span id="changeText"></span>
<script type="text/javascript">
var text = ["cool", "awesome", "outstanding"];
var counter = 0;
var elem = document.getElementById("changeText");
var refreshIntervalI = setInterval(change, 2000);
function change()
{
elem.innerHTML = text[counter];
counter++;
if (counter >= text.length) { clearInterval(refreshIntervalI); }
}
</script>
The output correctly displays each word after 2000ms, but it also takes 2sec to display the first word. How can I set a default value which will be displayed until the start of the loop?
Thanks in advance :)
Why not just like this
var text = ["cool", "awesome", "outstanding"];
var counter = 1;
var elem = document.getElementById("changeText");
elem.innerHTML = text[0];
var refreshIntervalI = setInterval(change, 2000);
function change()
{
elem.innerHTML = text[counter];
counter++;
if (counter >= text.length) { clearInterval(refreshIntervalI); }
}
Set the first value of your array as innerHTML on load and let the counter start at 1 and it should work as intended.
Try to call the function without setInterval() for the first time:
function change() {
...
}
change();

How to a create element and remove last added element after 1 sec intervals?

I have a list of element ids, for example 1, 2, 3 .....
I want to append a div to element 1, wait 1 second, remove the appended div from element 1 and then append a div to element 2, and so on for each element listed in seqIDs
Below is my code but I can't figure out how to remove the previous appended element or how to delay the loop by 1 second. I'm using vanilla javascript, so please no jQuery answers
for (var i = 0, len = seqIDs.length; i < len; i++) {
var newDiv = document.createElement('div');
document.getElementById(seqIDs[i]).appendChild(newDiv);
setTimeout(this.reset, 1000);
}
You can use setTimeout() to walk through the sequence, removing one and adding another on each timer call until you get to the end of the array:
(function() {
var cntr = 0;
var lastItem;
function next() {
if (lastItem) {
lastItem.parentNode.removeChild(lastItem);
lastItem = null;
}
if (cntr < seqIDs.length) {
var newDiv = document.createElement("div");
document.getElementById(seqIDs[cntr++]).appendChild(newDiv);
lastItem = newDiv;
setTimeout(next, 1000);
}
}
next();
})();
If you want it to just repeat itself over and over again, you can put it in a function that takes an argument for whether to repeat itself and then wrap cntr back to 0:
function cycleDiv(forever) {
var cntr = 0;
var lastItem;
function next() {
if (lastItem) {
lastItem.parentNode.removeChild(lastItem);
lastItem = null;
}
if (forever && cntr >= seqIDs.length) {
// wrap back to zero
cntr = 0;
}
if (cntr < seqIDs.length) {
var newDiv = document.createElement("div");
document.getElementById(seqIDs[cntr++]).appendChild(newDiv);
lastItem = newDiv;
setTimeout(next, 1000);
}
}
next();
}
cycleDiv(true);
To make one that you can start or stop at any time, you could do this:
function cycleDiv(forever) {
var cntr = 0;
var lastItem;
function next() {
if (lastItem) {
lastItem.parentNode.removeChild(lastItem);
lastItem = null;
}
if (forever && cntr >= seqIDs.length) {
// wrap back to zero
cntr = 0;
}
if (cntr < seqIDs.length) {
var newDiv = document.createElement("div");
document.getElementById(seqIDs[cntr++]).appendChild(newDiv);
lastItem = newDiv;
this.timer = setTimeout(next, 1000);
}
}
this.stop = function() {
clearTimeout(this.timer);
this.timer = null;
}
this.start = function() {
if (!this.timer) {
next();
}
}
}
var cycler = new cycleDiv(true);
cycler.start();
// then some time later
cycler.stop();
Also, it's a bit inefficient to keep creating and removing a new div element every second. I don't know what you're doing with the content of this div (since there's nothing in it in this code), but you could just have one div that you move from one parent to the next rather than continually making new div elements.

How to disable buttons after x amount of clicks in js?

I am trying to use Javascript to disable a button after it is clicked x amount of times. For simplicity sake lets say x = 2 for now. I cannot seem to get the counter to increment. Thank You for any help!
var $ = function (id) {
return document.getElementById(id);
}
window.onload = function () {
coke.onclick = function(){
var count =0;
if (count >= 1)
{
coke.disabled = true;
}
else
count++;
};
}
Where "coke" is the element ID. If i get rid of the if statement and just have coke.disabled = true, of course it works and disables after one click. I'm sure there is a core concept I am missing.
Thank You
This is happening because each time the onclick event is fired, your var count is being assigned to 0, so it will never be greater than or equal to one in your function. If you initialize the count var outside of the onclick function, it will behave as expected.
window.onload = function () {
var count = 0;
coke.onclick = function(){
if (count >= 1)
{
coke.disabled = true;
}
else
count++;
};
}
You need to define count outside the scope of your onclick function:
var $ = function (id) {
return document.getElementById(id);
}
var count = 0; // set initial count to 0
window.onload = function () {
coke.onclick = function(){
if (count >= 1)
{
coke.disabled = true;
}
else
count++;
};
}

Categories