Capturing counter value in Javascript closure [duplicate] - javascript

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 9 years ago.
The following code creates 10 elements under <body id="container" />. When i click on any element, I always see an alert with the value 10.
How can I get each alert to show the index of each element?
for (var i = 0; i < 10; ++i) {
var id = "#element_" + i;
$("#container").append('<p id="element_' + i + '">foo</p>');
$(id).click(function (e) {
alert(i);
});
}

You need either closure or simply use $.on() with data:
for (var i = 0; i < 10; ++i) {
var id = "#element_" + i;
$("#container").append('<p id="element_' + i + '">foo</p>');
$(id).on("click", i, function (e) { alert(e.data); });
}

Don't make functions inside for loops
for (var i = 0; i < 10; ++i) {
$("#container").append('<p id="element_' + i + '">foo</p>');
}
$("#container > p").click(function (e) {
var idNum = this.id.split('_')[1];
alert(idNum); // 0, 1, 2 ...
});
DEMO

need to create a private closure
for (var i = 0; i < 10; ++i) {
(function(idx){
var id = "#element_" + idx;
$("#container").append('<p id="element_' + idx + '">foo</p>');
$(id).click(function (e) {
alert(idx);
});
})(i)
}
Demo: Plunker

Related

Javascript AJAX Response, for loop difficulty [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
I have a little problem. Namely, I would like to get the value of my variable: count_green outside of my for loop. Has somebody an idea how I can do that?
Here is a snippet of my code:
function State(type, count, list_name){
var count_green = 0;
var count_yellow = 0;
var count_red = 0;
for (i = 0; i < count; i++){
var jqxhr = $.ajax( "/custom_data/getState/" + type[i]).done(function(result) {
for (j = 0; j < count; j++){
if(result.type == type[j]){
if(result.value == "GREEN"){
$("#" + type[j]).css("color","#468847");
count_green = count_green + 1;
}
if(result.value == "YELLOW"){
$("#" + type[j]).css("color","#f89406");
count_yellow = count_yellow + 1;
}
if(result.value == "RED"){
$("#" + type[j]).css("color","#b94a48");
count_red = count_red + 1;
}
}
}
});
}
//Here I would need the value of count_green, count_yellow and count_green
//Unfortunately they are outside of the for loop 0.
addCounters(count_green, count_yellow, count_red);
}
function addCounters(state_green, state_yellow, state_red){
$(".line").find(".list").append('<span class="badge pull-left count_badge badge-success">' + state_green + '</span>');
}
As you can see if I put the method call: addCounters in the for loop I get many badges why I need to access the count-variables: count_green, count_yellow and count_red outside of the for loop and ajax code.
I saw some solutions with callback but I need only one time the value of the variables, if I work with callback I get more then 1 time the values.
Thank you in advance.
One solution would be synchronous requests. http://api.jquery.com/jquery.ajax/ look at the async property.
$.ajax( "/custom_data/getState/" + type[i], {async: false}).done(...)
Another solution would look like this
var requestCount = 0;
for (i = 0; i < count; i++){
var jqxhr = $.ajax( "/custom_data/getState/" + type[i]).done(function(result) {
for (j = 0; j < count; j++){
if(result.type == type[j]){
if(result.value == "GREEN"){
$("#" + type[j]).css("color","#468847");
count_green = count_green + 1;
}
if(result.value == "YELLOW"){
$("#" + type[j]).css("color","#f89406");
count_yellow = count_yellow + 1;
}
if(result.value == "RED"){
$("#" + type[j]).css("color","#b94a48");
count_red = count_red + 1;
}
}
}
requestFinished(count_green, count_yellow, count_red);
});
}
function requestFinished(count_green, count_yellow, count_red){
requestCount++;
if(requestCount == count){//all requests finished
addCounters(count_green, count_yellow, count_red);
}
}

self executing anonymous click function in for loop

I need a click function in a for loop, so every id element is clickable. But I also need the i in the click function, that's why I thought a self executing anonymous function would be the best way to do so. But for some reason this is not working, maybe because the click function doesn't allow me to forward a parameter? What have I done wrong?
for (var i = 0; i < countItems; i++) {
$("#item-" + i).click(function(idx) {
alert(idx);
})(i)
}
The self executing function must return a function:
for (var i = 0; i < countItems; i++) {
$("#item-" + i).click(function(indx){
return function(){ //must return a function
alert(indx);
}
}(i));
}
JS Fiddle: http://jsfiddle.net/HuHXr/
As a side note, using bind() javascript method:
for (var i = 0; i < countItems; i++) {
$("#item-" + i).click(function(indx){
alert(indx);
}.bind($("#item-" + i)[0],i));
}
you can try something like this
for (var i = 0; i < countItems; i++) {
$("#item-" + i).click(clickFunctn);
}
function clickFunctn(obj){
var i=$(obj).attr('id').split('-')[1];
alert(i);
}
In this way you will optimize the code and your 'i' will be with you as well, and all items are clickable. And you are just binding one handler function.
for (var i = 0; i < countItems; i++) {
(function(i){
$("#item-" + i).click(function(idx) {
alert(idx);
});
})(i);
}
Also note that idx is the event object.
Fiddle: http://jsfiddle.net/2DRLx/

Remove elements slideshow

I try to remove my links one by one from div id="wrapper". But it doesn't work:
window.onload = function () {
setInterval(function () {
var wrapper = document.getElementById("wrapper");
var my_links = wrapper.getElementsByTagName("a");
var i;
for (i = 0; i < my_links.lenght + 1; i++) {
my_links.splice(0, i);
}
}, 5000);
}
What is the problem? How can i fix my snippet?
Typo here and length + 1 should be length - 1:
for (i=0; i<my_links.lenght+1; i++){
should be:
for (i=0; i<my_links.length-1; i++){
Further more
Look at this question over here to find the remove function you are looking for: Remove element by id
So it will be:
for (i=0; i<my_links.length-1; i++){
my_links[i].remove();
}
Remove function only works with the function of the question I posted.

JavaScript set DOM object event dynamically on dynamically created DOM objects

The following script:
var containerDIV = document.getElementById("sampleContainer");
for(var i = 0; i < 5; i++)
{
var dynamicDIV = document.createElement("div");
containerDIV.appendChild(dynamicDIV);
dynamicDIV.onclick = function() { alert(i); };
dynamicDIV.innerHTML = "Row: " + i;
}
when clicking on the dynamically rows the output in the alert box will always be "5" instead of 0, 1, ..
Do anyone knows a proper way to assign the onclick event?
You should use the closure power:
for (var i = 0; i < 5; i++) {
(function(i) {
dynamicDIV.onclick = function() {
alert(i);
};
})(i);
}
DEMO: http://jsfiddle.net/zvPfZ/

How can I refresh a Div in javascript instead of the whole page?

The code below works and is good but I am going to place it into a DRUPAL page and I would like it to refresh the "DIV" instead of the whole page. Can someone help? Thanks!
document.write("<div class='box1'><center><h1>Telling Time Worksheets</h1></center><div class='box_number_holder'>")
var nums = [01,02,03,04,05,06,07,08,09,10,11,12];
var gen_nums = [];
function in_array(array, el) {
for(var i = 0, j = array.length; i < j; i++)
if(array[i] == el) return true;
return false;
}
function get_rand(array) {
var rand = array[Math.floor(Math.random()*array.length)];
if(!in_array(gen_nums, rand)) {
gen_nums.push(rand);
return rand;
}
return get_rand(array);
}
for(var i = 0; i < 9; i++) {
document.write("<div class='box_numbers'><center>What Time is it?" + get_rand(nums) + "</center></div>");
}
Thanks!
Create a function that loops through all of your dynamically created div elements:
function refreshDivs() {
$('.box_numbers > center').each(function() {
$(this).html('What Time is it? ' + get_rand(nums));
});
}

Categories