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

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++;
};
}

Related

Assign random number to element in javascript but avoid duplicates

Please scroll down to bold text if you want to go straight to the question
I have made a page that consists of a grid of 9 tiles (divs).
Between 1-9 of those tiles could potentially have a slider inside it.
The sliders are all setup via a jQuery each function e.g
_gridSlider.each(function(){
// count slides, setup slider etc
}); // end slider each function
Everything works fine except the sliders all change at the same time and so I want to add some diversity into the start times.
Right now I create a random ID between 1 and X (X being the number of sliders) inside of the each function for each slider like so
_gridSlider.each(function(){
var _sliderID = Math.floor((Math.random() * _numSliders) + 1);
}); // end slider each function
I then start the sliders at a different time based around this ID like so
var _sliderStart = _sliderID + '000';
setTimeout(function() {
startTimer();
}, _sliderStart);
This works fine the only problem is that it is possible for 2 or more sliders to have the same ID, what I need is to assign each slider an ID between 1 and X but make sure that each slider has a different ID.
The end result would be have 1 timer starting at 1 second, another at 2 seconds, another at 3 seconds etc
You can use this function:
function generateId(numSliders) {
var store = generateId._store;
if (!store) {
generateId._store = {};
}
do {
var id = Math.floor(Math.random()*numSliders*1000+1);
} while (store[id])
store[id] = true;
return id;
}
Then you can use generated id as a start time:
var sliderId = generateId(slidersNumber);
var sliderStart = sliderId; // without + '000'
UPD generateId._store keeps used IDs inside itself. In that function store is used as a property of its function, to not add redundant variable to the namespace. You can put it outside of the generateId function. For example:
var store = {};
function generateId(numSliders) {
do {
var id = Math.floor(Math.random()*numSliders*1000+1);
} while (store[id])
return id;
}
But in that case you're polluting the namespace with redundant variable.
store inside of the function is used just to shorten the code a little. If you want you can write:
function generateId(numSliders) {
if (!generateId._store) {
generateId._store = {};
}
do {
var id = Math.floor(Math.random()*numSliders*1000+1);
} while (generateId._store[id])
generateId._store[id] = true;
return id;
}
An example using shuffle.
function createNumberSeries(howMany) {
var result = [];
for (var count = 1; count <= howMany; count += 1) {
result.push(count);
}
return result;
}
function shuffle(obj) {
var i = obj.length;
var rnd, tmp;
while (i) {
rnd = Math.floor(Math.random() * i);
i -= 1;
tmp = obj[i];
obj[i] = obj[rnd];
obj[rnd] = tmp;
}
return obj;
}
function createDivs(ids) {
var length = ids.length;
for (var index = 0; index < length; index += 1) {
var div = document.createElement('div');
div.id = ids[index];
div.className = 'initial';
document.body.appendChild(div);
}
}
function colourDivs(howMany) {
for (var index = 1; index <= howMany; index += 1) {
setTimeout((function(id) {
return function() {
document.getElementById(id).className += ' colorMe';
};
}(index)), index * 1000);
}
}
var numSliders = 10;
var sliderIds = shuffle(createNumberSeries(numSliders));
createDivs(sliderIds);
colourDivs(numSliders);
.initial {
height: 10px;
width: 10px;
border-style: solid;
border-width: 1px;
}
.colorMe {
background-color: blue
}

Need help getting this closure working

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/

Count element clicks and define an max

I tried to count an element clicks, and, in the right number call some action.
var count = 0;
document.getElementById("rolarbaixo").onClick = function(e) {
if( count >= 3 ) {
var elem = document.getElementById("noticia");
elem.setAttribute("style","top: 0px;");
}
else {
count ++;
}
};
When i clicked 3 times in the link "rolarbaixo" the div "noticia" set the "top: 0px;", but this doesn't work.
Why?
count ++ should be count++. If you press F12, you will be able to get to the developer tools and debug the javascript.
It's onclick in lowercase
var count = 0;
document.getElementById("rolarbaixo").onclick = function (e) {
if (count >= 2) {
var elem = document.getElementById("noticia");
elem.style.top = "0px";
} else {
count++;
}
};
FIDDLE
And it's >= 2 for three clicks (zero based and all).
AS the question is tagged jQuery, this would be it
$('#rolarbaixo').on('click', function() {
var clicked = $(this).data('clicked') || 0;
if (clicked >= 2) $('#noticia').css('top', 0);
$(this).data('clicked', ++clicked);
});
FIDDLE
Misprint in else statement and change onclick to lowercase:
var count = 0;
document.getElementById("rolarbaixo").onclick = function(e) {
if( count >= 3 ) {
var elem = document.getElementById("noticia");
elem.setAttribute("style","top: 0px;");
} else {
count++;
}
};

Scoring a Javascript Quiz Script

Hi I some javascript code written to quiz the user on 5 questions and then in theory output their score. As far as I can tell the questions are being scored, I just can't figure out how to output the response. I am having no issues fetching the correct html elements and displaying them. I believe the issue is in the looping elements of the window.onload function. The code is below,
<script type="text/javascript">
var rand = 0;
var right = 0;
window.onload = function () {
reset();
Rrand();
var rangQ = document.getElementById('area').getElementsByClassName('divide');
correct = document.getElementsByTagName('a'), i = 0;
for (i; i < correct.length; i++) {
if (correct[i].className == 'correct') {
correct[i].onclick = function () {
right++;
reset();
Rrand();
}
}
else if (correct[i].className != 'correct') {
correct[i].onclick = function () {
right--;
reset();
Rrand();
}
}
}
}
function Rrand() {
var rangQ = document.getElementById('area').getElementsByClassName('divide');
rangQ[rand].style.display = '';
rand++;
}
function reset() {
var rangQ = document.getElementById('area').getElementsByClassName('divide');
for (var i = 0; i < rangQ.length; i++) {
rangQ[i].style.display = 'none';
}
}
document.write(right);
</script>
window.onload is not executed immidiately. you are writing output, but variable right is changed after that.
you need to either move line
document.write(right);
into window.onload as last line (or after loop) or figure out other way that will be best for you

Javascript content rotator?

I’ve got the basics of a content rotator done, the only problem is it doesn’t loop itself back to the beginning and I cannot figure out why! It is a very simple javascript script:
window.onload = function() { setInterval("transition()", 5000); }
function transition()
{
var y = document.getElementById("featured").getElementsByTagName("li");
for (var i=0;i<y.length;i++)
{
if (y[i].className == "current")
{
y[(i+1)].className = "current";
y[i].className = "";
break;
}
}
}
It keeps stopping at the end of the list, basically I just want it to loop. Any help?
You can make this a little smarter by taking advantage of the wonderful language that is Javascript:
window.onload = function() {
var y = document.getElementById('featured').getElementsByTagName('li');
var ylen = y.length, index = 0;
y[0].className = 'current';
setInterval(function() {
y[index].className = '';
index = (index + 1) % ylen;
y[index].className = 'current';
}, 5000);
};
When you pre-define the list of <li> elements like that, the function you provide for the interval timer can reference them every time the timer fires. The index variable increments up until it hits the end of the array, and then it'll be set back to zero.
try this:
if (y[i].className == "current")
{
if (y[i+1]]
y[i+1].className = "current";
else
y[0].className = "current";
y[i].className = "";
break;
}
First time you loop you set the last elements class "current". You should put something like
y[0].className = "current"
when you reach and of the loop.

Categories