Javascript counter++ skips counting - javascript

I am building a simple JS game but ++ keeps on adding up for no reason.
Here is the code:
var cities = ["Atlanta","Chicago","Honolulu","Houston","Nashville","Orlando","Philadelphia","Phoenix","Portland","Seattle"],
c = Math.floor((Math.random() * 10)),
city = cities[c].toUpperCase(),
cityArr = city.split(""),
length = city.length,
guess = 0,
$prompt = $('#prompt'),
x, //letter guess
i;
function randomCity() {
var $showCity = document.getElementById("showCity"), //ul
newLi,
letter;//each letter of city
for(i=0; i<cityArr.length; i++){
newLi = document.createElement("li");
$showCity.appendChild(newLi);
letter = document.createTextNode(cityArr[i]);
newLi.appendChild(letter);
}
$("#showCity li").css("color", "#fff");
}//end randomCity()
function play() {
if(guess == 6){
$("#alphabet").css("visibility", "hidden");
ending();
} else {
$prompt.fadeIn("slow").text("Guess a letter: ");
guessLetter();
}
} // end play function
function guessLetter() {
var showLetter;
guess++
console.log(guess); //SHOWS THE COUNTER ADDING UP CONTINUOUSLY AFTER 2
$("#alphabet li").on('click', function () {
$(this).css("visibility", "hidden");
x = this.id;
if (city.indexOf(x) == -1) {
$prompt.fadeIn("slow").text("No letter " + x);
setTimeout(play, 1500);
} else {
for (i = 0; i < length; i++) {
if (city[i] == x) {
$prompt.fadeIn("slow").text("There is letter " + x + "!");
showLetter = "#showCity li:nth-child("+(i+1)+")";
$(showLetter).css("color", "#0F9ED8");
}
} //for loop
setTimeout(play, 1500);
} //else
});
}
function ending(){ //STILL IN PROGRESS
var guessWord,
finalOutput;
$prompt.fadeIn("slow").text("What is the word? ");
//guessWord = word from input
finalOutput = (guessWord == city) ? "That is correct!" : "Sorry, that is wrong.";
$prompt.fadeIn("slow").text(finalOutput);
}
$(document).ready(function(){
$("#start").on('click', function() {
$(this).hide();
randomCity();
console.log(city);
$("#alphabet").css("visibility", "visible");
play();
});
}); // end ready
variable guess (the counter) has value of 4 after clicking the 2nd element, and has a value of 6 after clicking the 3rd element. I moved the var guess in different parts of my code but it is still doing that. This is very weird!

By doing
$("#alphabet li").on('click', function () { /* ... */}`
you're binding a new click handler every time the guessLetter() function gets executed. Multiple click handlers will call the play() function which in turn calls the guessLetter() function again, resulting in guess being incremented multiple times.
Bind the click handler only once.

You are attaching a new click handler to your list items every time the guessLetter function is called.
To fix it, you could move everything in guessLetter which occurs after your console.log call into the $(document).ready callback function.

Related

JS random order showing divs delay issue

I got function within JS which is supposed to show random order divs on btn click.
However once the btn is clicked user got to wait for initial 10 seconds ( which is set by: setInterval(showQuotes, 10000) ) for divs to start showing in random order which is not ideal for me.
JS:
var todo = null;
var div_number;
var used_numbers;
function showrandomdivsevery10seconds() {
div_number = 1;
used_numbers = new Array();
if (todo == null) {
todo = setInterval(showQuotes, 10000);
$('#stop-showing-divs').css("display", "block");
}
}
function showQuotes() {
used_numbers.splice(0, used_numbers.length);
$('.container').hide();
for (var inc = 0; inc < div_number; inc++) {
var random = get_random_number();
$('.container:eq(' + random + ')').show();
}
$('.container').delay(9500).fadeOut(2000);
}
function get_random_number() {
var number = randomFromTo(0, 100);
if ($.inArray(number, used_numbers) != -1) {
return get_random_number();
} else {
used_numbers.push(number);
return number;
}
}
function randomFromTo(from, to) {
return Math.floor(Math.random() * (to - from + 1) + from);
}
Question: How to alter the code so upon the btn click divs will start showing right away without initial waiting for 10 seconds? (take in mind I want to keep any further delay of 10 seconds in between of each div being shown)
Thank you.
Call it when you begin the interval
todo = setInterval((showQuotes(),showQuotes), 10000);

Execute only one function using self-invoking function in a for loop and exit

I want to implement a clicker by a user and by a computer randomly . I need to stop user click event after one cell is clicked .My random function is not executing .It is because left self-invoking functions are waiting to be clicked.You need to click only one cell(id) and continue executing random function .
for(var i=0;i<temp.length;i++){
(function (index){
if(!once) {
$(temp[index]).click(function(e){
if($(temp[index]).text()=="" && !once && turns%2==0){
$(temp[index]).text(player1Val);
console.log("first player clicked ");
once = true;
turns++;
return;
}
});
} //if
else {
console.log("break out ");
return false;
}
})(i);
}
function generateRandom(){
var temp = [];
cnt++;
for(var i=0;i<ids.length;i++){
if($(ids[i]).text()==""){
temp.push(ids[i]);
}
}
var id = Math.floor(Math.random()*temp.length);
if(temp.length>0 && turns%2==1){
$(temp[id]).text(player2Val);
turns++;
}
return id;
}

For loop using jQuery and JavaScript

I'm trying to do a simple for loop in JavaScript/jQuery
every time I click NEXT, I want the I to increment once.
But it is not working. When I press next, nothing happens.
<script>
//function to show form
function show_form_field(product_field){
$(product_field).show("slow");
}
$(document).ready(function(){
//start increment with 0, until it is reach 5, and increment by 1
for (var i=0; i < 5 ;i++)
{
//when I click next field, run this function
$("#next_field").click(function(){
// fields are equial to field with id that are incrementing
var fields_box = '#field_'+[i];
show_form_field(fields_box)
})
}
});
</script>
You do not need the for loop. Just declare var i outside click function and increment it inside the function.
//function to show form
function show_form_field(product_field) {
$(product_field).show("slow");
}
$(document).ready(function () {
var i = 0; // declaring i
$("#next_field").click(function () {
if (i <= 5) { // Checking whether i has reached value 5
var fields_box = '#field_' + i;
show_form_field(fields_box);
i++; // incrementing value of i
}else{
return false; // do what you want if i has reached 5
}
});
});
You should declare variable i document wide, not inside the click handler.
//function to show form
function show_form_field(product_field){
$(product_field).show("slow");
}
$(document).ready(function(){
var i=0;
$("#next_field").click(function(){
var fields_box = '#field_'+ i++ ;
show_form_field(fields_box)
})
});
Call $("#next_field").click just one time, and in the click function, increase i every time.
$(document).ready(function() {
var i = 0;
$("#next_field").click(function() {
if (i >= 5) {
//the last one, no more next
return;
}
show_form_field('#field_' + (i++));
});
});
try this
$(document).ready(function(){
//start increment with 0, untill it is reach 5, and increment by 1
var i = 0;
$("#next_field").click(function(){
// fields are equial to field with id that are incrementing
if(i<5)
{
var fields_box = '#field_'+i;
show_form_field(fields_box);
i+=1;
}
else
{
return;
}
});
});

jQuery "keyup" crashing page when checking 'Word Count'

I have a word counter running on a DIV and after typing in a few words, the page crashes. The browser continues to work (par scrolling) and no errors are showing in Chrome's console. Not sure where I'm going wrong...
It all started when I passed "wordCount(q);" in "keyup". I only passed it there as it would split-out "NaN" instead of a number to countdown from.
JS:
wordCount();
$('#group_3_1').click(function(){
var spliced = 200;
wordCount(spliced);
}) ;
$('#group_3_2').click(function(){
var spliced = 600;
wordCount(spliced);
}) ;
function wordCount(q) {
var content_text = $('.message1').text(),
char_count = content_text.length;
if (char_count != 0)
var word_count = q - content_text.replace(/[^\w ]/g, "").split(/\s+/).length;
$('.word_count').html(word_count + " words remaining...");
$('.message1').keyup(function() {
wordCount(q);
});
try
{
if (new Number( word_count ) < 0) {
$(".word_count").attr("id","bad");
}
else {
$(".word_count").attr("id","good");
}
} catch (error)
{
//
}
};
HTML:
<input type="checkbox" name="entry.3.group" value="1/6" class="size1" id="group_3_1">
<input type="checkbox" name="entry.3.group" value="1/4" class="size1" id="group_3_2">
<div id="entry.8.single" class="message1" style="height: 400px; overflow-y:scroll; overflow-x:hidden;" contenteditable="true"> </div>
<span class="word_count" id="good"></span>
Thanks in advanced!
This is causing an infinite loop if (new Number(word_count) < 0) {.
Your code is a mess altogether. Just study and start with more basic concepts and start over. If you want to describe your project to me in a comment, I would be glad to show you a good, clean, readable approach.
Update:
Part of having a good architecture in your code is to keep different parts of your logic separate. No part of your code should know about or use anything that isn't directly relevant to it. Notice in my word counter that anything it does it immediately relevant to its word-counter-ness. Does a word counter care about what happens with the count? Nope. It just counts and sends the result away (wherever you tell it to, via the callback function). This isn't the only approach, but I just wanted to give you an idea of how to approach things more sensefully.
Live demo here (click).
/* what am I creating? A word counter.
* How do I want to use it?
* -Call a function, passing in an element and a callback function
* -Bind the word counter to that element
* -When the word count changes, pass the new count to the callback function
*/
window.onload = function() {
var countDiv = document.getElementById('count');
wordCounter.bind(countDiv, displayCount);
//you can pass in whatever function you want. I made one called displayCount, for example
};
var wordCounter = {
current : 0,
bind : function(elem, callback) {
this.ensureEditable(elem);
this.handleIfChanged(elem, callback);
var that = this;
elem.addEventListener('keyup', function(e) {
that.handleIfChanged(elem, callback);
});
},
handleIfChanged : function(elem, callback) {
var count = this.countWords(elem);
if (count !== this.current) {
this.current = count;
callback(count);
}
},
countWords : function(elem) {
var text = elem.textContent;
var words = text.match(/(\w+\b)/g);
return (words) ? words.length : 0;
},
ensureEditable : function(elem) {
if (
elem.getAttribute('contenteditable') !== 'true' &&
elem.nodeName !== 'TEXTAREA' &&
elem.nodeName !== 'INPUT'
) {
elem.setAttribute('contenteditable', true);
}
}
};
var display = document.getElementById('display');
function displayCount(count) {
//this function is called every time the word count changes
//do whatever you want...the word counter doesn't care.
display.textContent = 'Word count is: '+count;
}
I would do probably something like this
http://jsfiddle.net/6WW7Z/2/
var wordsLimit = 50;
$('#group_3_1').click(function () {
wordsLimit = 200;
wordCount();
});
$('#group_3_2').click(function () {
wordsLimit = 600;
wordCount();
});
$('.message1').keydown(function () {
wordCount();
});
function wordCount() {
var text = $('.message1').text(),
textLength = text.length,
wordsCount = 0,
wordsRemaining = wordsLimit;
if(textLength > 0) {
wordsCount = text.replace(/[^\w ]/g, '').split(/\s+/).length;
wordsRemaining = wordsRemaining - wordsCount;
}
$('.word_count')
.html(wordsRemaining + " words remaining...")
.attr('id', (parseInt(wordsRemaining) < 0 ? 'bad' : 'good'));
};
wordCount();
It's not perfect and complete but it may show you direction how to do this. You should use change event on checkboxes to change wordsLimit if checked/unchecked. For styling valid/invalid words remaining message use classes rather than ids.
I think you should use radio in place of checkboxes because you can limit 200 or 600 only at a time.
Try this like,
wordCount();
$('input[name="entry.3.group"]').click(function () {
wordCount();
$('.word_count').html($(this).data('val') + " words remaining...");
});
$('.message1').keyup(function () {
wordCount();
});
function wordCount() {
var q = $('input[name="entry.3.group"]:checked').data('val');
var content_text = $('.message1').text(),
char_count = content_text.length;
if (char_count != 0) var word_count = q - content_text.replace(/[^\w ]/g, "").split(/\s+/).length;
$('.word_count').html(word_count + " words remaining...");
try {
if (Number(word_count) < 0) {
$(".word_count").attr("id", "bad");
} else {
$(".word_count").attr("id", "good");
}
} catch (error) {
//
}
};
Also you can add if your span has bad id then key up should return false;
See Demo

Recursive loop in javascript with increment based on a link click

I'm populating form fields and prompting the user through them using a javascript recursive loop.
I'm having a problem with the recursion not working as expected.
I have a recursive loop that prompts a user through 6 input fields.
field1 and field2 populate as expected, but field3 and field4 fire off together and field5 and field6 fire off together.
I think it has something to do with global vs. local variables or possibly scoping inside the loop() function, but I'm struggling with figuring it out.
JSFiddle: http://jsfiddle.net/9QtDw/5/
Click on the "Save Data" button to fire off the loop and you can see the loop() function iterate with confirm popups guiding the user.
Any help pointing me in the right direction is greatly appreciated.
var x = 0;
var fieldnames = ["field1", "field2", "field3", "field4", "field5", "field6"]
function loop(y) {
i = y;
if (i >= fieldnames.length) { // check to see if loop has run through the number of elements in the fieldnames array
return;
}
confirm( 'Highlight the ' + fieldnames[i] + ' text' );
console.log("outside on click function i=" + i);
//function to be called when button is clicked
$("#text-submit").on("click", function(){
//fieldinfo = $("#cs-ResultText").text();
$('#' + fieldnames[i] + '').val('this is where i = ' + i);
// increment i and recall the loop function for the next field
if(i >= fieldnames.length - 1 ){ return false; }
i=i+1;
console.log(i);
console.log("inside on click function i=" + i);
return loop(i); // the recusive call back into the loop
});
return false;
}
// only fire off the loop call on the first run through, after that it's called on #text-submit click
if( x === 0 ){
loop(x);
}
try this instead:
var x = 0;
var fieldnames = ["field1", "field2", "field3", "field4", "field5", "field6"]
function loop(y) {
i = y;
if (i >= fieldnames.length) { return; }
confirm( 'Highlight the ' + fieldnames[i] + ' text' );
$('#' + fieldnames[i] + '').val('this is where i = ' + i);
return false;
}
$("#text-submit").on("click", function(e){
e.preventDefault();
if(i >= fieldnames.length - 1 ){ return false; }
i=i+1;
loop(i);
});
if( x === 0 ){
loop(x);
}
working fiddle here: http://jsfiddle.net/9QtDw/6/
I hope it helps.
You are not looping!!!
ya just loop for 2 time
you should change your loop function like this:
function loop(y) {
i = y;
if (i >= fieldnames.length) { // check to see if loop has run through the number of elements in the fieldnames array
return;
else
$("#text-submit").trigger('click')
}

Categories