Jquery click event causing loop to execute only one time - javascript

I want to show next five divs each time when i click show more button, 5 divs will be shown default when load, here is my code,
var counterBox = 5;
$("#show_more_location").click(function() {
$(".loading-container").show();
for (var inc = 5; inc <= 5; inc++) {
if(counterBox<50){
counterBox = counterBox + 1;
$(".location-box:nth-child("+counterBox+")").slideDown().addClass("show_box").delay(100);
}
}
$(".loading-container").delay(5000).hide();
});
Problem is that when I click show more button, it loops only once, and stops. Only one div is showing ,I want to show 5 divs on show buttonclick.
Can anyonehelp?

It seems you init your inc iterator with 5, and get out of the loop when it's higher than 5:
for (var inc = 5; inc <= 5; inc++) {
...
}
Try initializing it with 1:
for (var inc = 1; inc <= 5; inc++) {
...
}

You're setting inc in the for loop to 5, then checking if it is lower than or is 5. So it runs once. Make inc 0 to run it 6 times.

Related

JavaScript Pagination Only show 5 buttons

I have created a pagination system using JavaScript. I have used this code to create the pagination system:
function setUpPagination(items, wrapper, rows_per_page) {
wrapper.innerHTML = "";
let page_count = Math.ceil(items.length / rows_per_page);
for (let i = 1; i < page_count + 1; i++) {
let btn = paginationButton(i, items);
wrapper.appendChild(btn);
}
}
function paginationButton(page, items) {
let button = document.createElement('button');
button.innerText = page;
if (current_page == page) {
button.classList.add('active');
}
button.addEventListener('click', function() {
current_page = page;
displayList(items, list_element, rows, current_page);
let current_btn = document.querySelector('.pagination button.active');
current_btn.classList.remove('active');
button.classList.add('active');
})
return button;
}
However, this code shows all of the pagination buttons. If I have 100 pages, all 100 pagination buttons will be shown.
I only want to show 5 buttons at a time. These buttons should be: the page the user is currently on, the 2 pages before the page the user is currently on, the 2 pages after the page the user is currently on.
If the user is on page 1, pages 1 - 5 should be shown.
If the user is on the last page, the last page button and the 4 page buttons before that should be shown.
I have added this code to stop the user from selecting a page which is too high:
if (i >= page_count) {
i = page_count;
}
However this means the user cannot select the last two pages.
I want to give the user the ability to select the last two pages. However, no extra pages should be shown.
With the way you have set up your for-loop bounds in your setUpPagination function, you are iterating over every single page and making a button for each one. I recommend you update the loop bounds to only cover the range of pages you want buttons for.
I envision an update that looks something like this:
for (let i = current_page - 2; i <= current_page + 2; i++) { // <-- HERE!
let btn = paginationButton(i, items);
wrapper.appendChild(btn);
}
}
Of note, this won't properly account for when you are looking at the first few or last few pages, so you will want to update this slightly to account for these edge cases (for example, if you are viewing page 1 currently this would attempt to make buttons for pages -1, 0, 1, 2, & 3). I think this should give you a good push in the right direction though!
This function will return five pages, current in the middle and first/last five if necessary:
const result = getPages(3, 19);
console.log(result);
function getPages(totalPages, currentPage) {
if (totalPages <= 5) return Array.from(Array(totalPages).keys()).map( r => { return r + 1 });
let diff = 0;
const result = [currentPage - 2, currentPage - 1, currentPage, currentPage + 1, currentPage + 2];
if (result[0] < 3 ) {
diff = 1 - result[0];
}
if (result.slice(-1) > totalPages - 2 ) {
diff = totalPages - result.slice(-1);
}
return result.map( r => { return r + diff });
}
Case total 5, current from 1 to 5 returns [1,2,3,4,5].
Case total less than 5, returns an array of number of total length.
Case total 15, current 13, 14 or 15 returns [11,12,13,14,15].

how to make number generator similar to google number generator

Im trying create some type of number generator on webpage. I want to show like five numbers before the generated number show. For better imagine, you can look to google generator. When you click generate, it shows like 3-4 numbers before generated number. I use setInterval or setTimeout but i dont know how it works. My js code:
var button = document.querySelector("button");
button.addEventListener("click",function() {
for (var i = 0; i < 8; i++) {
setInterval(textC,5);
}
});
function textC(){
number.textContent = Math.floor(Math.random() * 1000) + 1;
}
Thanks for every help!
The issue with setInterval() is that it will continue forever unless cleared, causing you to keep generating random numbers. Instead you can use setTimeout(), but set the timeout to change based on the value of i in the for loop. That way, each interval will occur 50 m/s after the other.
See example below:
const button = document.querySelector("button");
const number = document.querySelector("#number");
button.addEventListener("click", function() {
for (let i = 0; i < 5; i++) {
setTimeout(textC, 50 * i);
}
});
function textC() {
number.textContent = Math.floor(Math.random() * 1000) + 1;
}
<p id="number"></p>
<button>Generate</button>
Don't use a loop (why not?). Just nest setTimeout and call it until a predefined threshold is reached. It gives you maximum control.
var button = document.querySelector("button");
var number = document.querySelector("#number");
const nRuns = 12;
const timeout = 100;
let iterator = 0;
button.addEventListener( "click", textC);
function textC(){
number.textContent = `${Math.floor(Math.random() * 1000) + 1}\n`;
iterator += 1;
if (iterator < nRuns) {
setTimeout(textC, timeout)
} else{
iterator = 0;
// you control the loop, so it's time for some extra text after it
number.textContent += ` ... and that concludes this series of random numbers`;
}
}
<p id="number"></p>
<button>Generate</button>

When click print from 1 to 10, on the second click print from 10 to 20 etc

I'm trying to make a button where the user can click and that what will happen:
var score = 0;
document.getElementById('button').addEventListener('click', addScore);
function addScore() {
score += 5;
}
And now it's the step that I don't know how to make:
When the user click the button the function addScore should work, after this function worked, there is something need to be printed on the screen:
and it must be for the first click:
1
2
3
4
5
on the secound click the printed text must be
6
7
8
9
10
etc
You can add a loop and, with a bit of math, calculate the range of numbers that you need to add with each click.
var clicked = 0;
const div = document.querySelector('div');
document.querySelector('button').addEventListener('click', addScore);
function addScore() {
// Get the new range
// e.g initially this will be 1 (5 * 0) + 1
const range = (5 * clicked) + 1;
// Set up a new array to which we will add the numbers
let arr = [];
// Loop from range to range + 5 and push each
// number into the array
for (let i = range; i < range + 5; i++) {
arr.push(i);
}
// Join the array with a `<br/>` element and add it to before the
// end of your output div
div.insertAdjacentHTML('beforeend', `${arr.join('<br/>')}<br/>`);
// Increase the click value
++clicked;
}
<button>Click</button>
<div></div>
Use the following code:
var score = 0;
document.getElementById('button').addEventListener('click', addScore);
function addScore() {
var html = '';
for (var i=0; i<5; i++) {
html+=(score+1)+'<br>';
score++;
}
document.getElementById('#idofcontentdiv').innerHTML = html;
}
This increments score upto next 5 iterations and keeps its value into a variable 'html', then use the variable to put into a dom element content.
Add following inside addScore() method :
function addScore(){
for(var i = 0; i < 5; i++)
console.log(++score)
}
Variable score should be initialized to 0
Since you have not specified where exactly to print, I am assuming it is console.
Edit: i got working example here is fiddle: https://jsfiddle.net/apd0z7ho/
html
var score = 0;
<button id="button">click me</button>
<p id="results"></p>
javascript
var score = 0;
document.getElementById('button').addEventListener('click', addScore);
function addScore() {
score += 5;
for(var i = score-5; i < score; i++){
document.getElementById("results").innerHTML += i+1+"<br>";
}
}

How to loop a function in javascript

I have four different button effects where each effect are declared in a variable.
Therefore, I bring all of these four variables and place them within an array called arr in which is used in the clickByItself() function using Math.floor(Math.random()) methods.
Without the for loop, the code clicks by itself randomly in one of the four buttons every time I reload the page.
function clickByItself() {
let random = Math.floor(Math.random() * arr.length);
$(arr[random]).click();
}
However, using the for loop I am not being able to make these clicks one-by-one within the maximum of 10 times.
var blueButtonEffect = code effect here;
var redButtonEffect = code effect here;
var greenButtonEffect = code effect here;
var yellowButtonEffect = code effect here;
var arr = [blueButtonEffect, redButtonEffect, greenButtonEffect, yellowButtonEffect];
//will click on buttons randomly
function clickByItself() {
let random = Math.floor(Math.random() * arr.length)
var i;
for (i = 0; i < 10; i++) {
$(arr[random]).click();
setTimeout(clickByItself(), 1000);
}
}
The final output with the current code above is the four buttons being clicked at the same time, not one-by-one.
So, how can I have this function to press a random button by 10 times one-by-one with one second of interval from each click?
To fix your code you need:
A base case for your recursion
Pass a function reference to setTimeout. Currently, you are executing clickByItself and passing its return value (which is undefined) to setTimeout.
Do not use setTimeout in a loop without increasing the time by a factor of i, as the for loop will queue all the function calls at the same time
Alternatively, you can use a "times" argument to avoid looping
You could try something like
function clickByItself(times = 0) {
let random = Math.floor(Math.random() * arr.length)
$(arr[random]).click();
if (++times < 10) {
setTimeout(function(){clickByItself(times);}, 1000);
}
}
An example with console logs
https://jsfiddle.net/pfsrLwh3/
The problem is that the for loop calls the setTimeout 10 times very quickly. If you want to wait until the previous function call finishes prior to calling the next, then you should use recursion or just use a setInterval.
Recursion:
function clickByItself(numIterations) {
let random = Math.floor(Math.random() * arr.length)
let i;
$(arr[random]).click();
if( numIterations < 10 ){
setTimeout(() => {
clickByItself(numIterations += 1)
}, 1000)
}
}
clickByItself(0);
With setInterval
let numIterations = 0;
function clickByItself() {
let random = Math.floor(Math.random() * arr.length);
let i;
$(arr[random]).click();
numIterations += 1;
if( numIterations > 10) {
clearInterval(loop)
}
}
let loop = setInterval(test2, 1000);
Are you saying this is working for only 4 times but I think your above code will run in an infinite loop as you are calling clickByItself() again in the for loop.
If you want press a random button by 10 times one-by-one with one second of interval from each click then replace the for loop with
for (i = 0; i < 10; i++) {
setTimeout($(arr[random]).click(), 1000);
}

setTimeout to access DOM in for loop

Please look at this codepen: http://codepen.io/dragonOne/pen/rrwrQw (doesn't work yet!)
I want this Javascript memory board to display cards one by one in spiral order.
The spiralOrder(output) function takes in a matrix of div id's and changes each card div (id is tile_i) to display = "block" one by one in spiral order, every two seconds. But my setTimeout isn't working properly and is only displaying the first four cards (all at once...)
When I read the console.log in spiralOrder I see that the function correctly reads each card in the order that I want. But how come my setTimeout isn't working to add delay after every card display?
function spiralOrder(output) {
// Initialize our four indexes
var top = 0;
var down = output.length - 1;
var left = 0;
var right = output[0].length - 1;
var regexp = /\d+/g;
while(true)
{
// Starting showing top row
for(var j = left; j <= right; ++j) {
console.log("tile_"+output[top][j].match(regexp)); //THIS SHOWS SPIRAL ALGORITHM IS CORRECT
setTimeout(function() { document.getElementById("tile_"+output[top][j].match(regexp)).style.display = "block"; }, 2000); //THIS DOESN'T BEHAVE RIGHT
}
top++;
if(top > down || left > right) {
break;
}
//Starting showing rightmost column
for(var i = top; i <= down; ++i){
console.log("tile_"+output[i][right].match(regexp));
setTimeout(function() { document.getElementById("tile_"+output[i][right].match(regexp)).style.display = "block"; }, 2000);
}
right--;
if(top > down || left > right) {
break;
}
//Starting showing bottom row
for(var j = right; j >= left; --j){
console.log("tile_"+output[down][j].match(regexp));
setTimeout(function() { document.getElementById("tile_"+output[down][j].match(regexp)).style.display = "block"; }, 2000);
}
down--;
if(top > down || left > right) {
break;
}
//Starting showing leftmost column
for(var i = down; i >= top; --i){
console.log("tile_"+output[i][left].match(regexp));
setTimeout(function() { document.getElementById("tile_"+output[i][left].match(regexp)).style.display = "block"; }, 2000);
}
left++;
if(top > down || left > right) {
break;
}
}
}
What is going wrong here?
You are trying to use setTimeout as a pause function. That isn't what it does. It just ensures that the contained function is called around the offset time. So, in your code, it is running through all of the divs and scheduling all the calls to occur simultaneously in about 2 seconds.
Couple of possible solutions
(POOR) Rewrite the code to call the timeout functions at (count++)*2000 so they are called successively
(BETTER) Rewrite the code so that the timeout function updates one div and then updates state and sets another timeout to perform the next update (and so on). Basically unwrap your loops into a series of timeout callbacks.
Update: take a look at How do I add a delay in a JavaScript loop?

Categories