2010-08-16 158 views
0

我有一个循环,当它被调用时,创建一个带有一些表单元素的div。每个div都基于一个变量,“i”赋予字段和div唯一的名称。有没有一种方法可以将变量存储在创建div的位置?在循环中获取变量的值

例如,创建了div1,并且其中的所有内容都具有附加到名称的1(变量)。表单元素相互依赖,并由ID调用。问题是,当我创建一个新的div并将变量(i)更改为2时,第一组表单元素尝试使用2而不是1.

有意义吗?

编辑:这是一些代码。这很麻烦,所以我提前道歉。

var i = 0; 

    $('a#add-product').click(function(event){ 
     i++; 
     $('<div />').addClass('product').attr('id', 'product'+i) 
      .append($('<h2><img src="<?php echo base_url();?>img/product.png" alt="" />Product '+i+'</h2>')) 
      .append($('<div class="info-line"><label>Division</label><p><select id="selection-'+i+'" class="selection"><option value="">- Select a Division -</option><option value="abrasives">Abrasives</option><option value="tapes">Bonding, Surface Protection &amp; Tapes</option><option value="packaging">Packaging</option></select></p></div>')) 
      .append($('<div class="info-line"><label>Category</label><p><select id="selectionresult-'+i+'" name="selectionresult-'+i+'" class="selectionresult"></select><span id="result-'+i+'" class="result">&nbsp;</span></p></div>')) 
      .append($('<div class="info-line"><label>Product</label><p><select id="selectionresult2-'+i+'" name="selectionresult2-'+i+'" class="selectionresult2"></select><span id="result2-'+i+'" class="result2">&nbsp;</span></p></div>')) 
      .append($('<a class="remove" href="#add-product" id="remove-product'+i+'"><img src="<?php echo base_url();?>img/remove-product.jpg" alt="" />Remove Product</a>')) 
      .appendTo("#products"); 

      // START OF ADDITIONAL PRODUCT DROP DOWNS 

        $("#selectionresult-"+i).hide(); 
        $("#selectionresult2-"+i).hide(); 

        $("#selection-"+i).change(function() { 

         $(this).next(".selectionresult").hide(); 
         $(this).next(".selectionresult2").hide(); 
         $("#result-"+i).html('Retrieving ...'); 
         $.ajax({ 
          type: "POST", 
          data: "data=" + $(this).val(), 
          url: "<?php echo base_url();?>dropdown.php", 
          success: function(msg){ 
           if (msg != ''){ 
            $("#selectionresult-"+i).html(msg).show(); 
            $("#result-"+i).html(''); 
           } 
           else{ 
            $("#result-"+i).html('<em>No item result</em>'); 
           } 
          } 
         }); 

        }); 
        $("#selectionresult-"+i).change(function() { 
         $(this).next(".selectionresult2").hide(); 
         $("#result2-"+i).html('Retrieving ...'); 
         $.ajax({ 
          type: "POST", 
          data: "data=" + $(this).val(), 
          url: "<?php echo base_url();?>dropdown.php", 
          success: function(msg){ 
           if (msg != ''){ 
            $("#selectionresult2-"+i).html(msg).show(); 
            $("#result2-"+i).html(''); 
           } 
           else{ 
            $("#result2-"+i).html('<em>No item result</em>'); 
           } 
          } 
         }); 
        }); 
    }); 
+1

告诉我codez – roryf 2010-08-16 13:42:01

+1

粘贴一些代码,请。 – Chris 2010-08-16 13:42:06

回答

2

您可以将需要在这样一个封闭引用的i正确版本的代码:

var i = 0; 

$('a#add-product').click(function(event){ 
    i++; 

    // Begin closure. When called (at the end of the closure) it receives 
    // the current value of "i". This value of "i" will be referenced 
    // throughout the closure as a local variable containing the value 
    // you expect, instead of the "shared" "i" variable outside the 
    // closure. 
    (function(i) { 

     // So basically we've created a new "scope" inside here. Now "i" 
     // is a separate local variable than the "i" variable ouside 
     // the closure. You could change the variable name by changing 
     // the parameter above. Like (function(my_i) {... 
     // If you did that, you would need to change the "i" in your .change() 
     // handlers to "my_i". The rest of them could stay the same, or you 
     // could change them. Either way would work. 
     // This is because the .change() handlers are executed at a later time 
     // (and so are the AJAX callbacks) so they need to use the variable 
     // that is local to this closure. 
     // The rest of the code, like $("#selectionresult-" + i) is executing 
     // immediately, so it could reference the "i" variable that is 
     // outside the closure, and still work properly. 

     $('<div />').addClass('product').attr('id', 'product'+i) 
      .append($('<h2><img src="<?php echo base_url();?>img/product.png" alt="" />Product '+i+'</h2>')) 
      .append($('<div class="info-line"><label>Division</label><p><select id="selection-'+i+'" class="selection"><option value="">- Select a Division -</option><option value="abrasives">Abrasives</option><option value="tapes">Bonding, Surface Protection &amp; Tapes</option><option value="packaging">Packaging</option></select></p></div>')) 
      .append($('<div class="info-line"><label>Category</label><p><select id="selectionresult-'+i+'" name="selectionresult-'+i+'" class="selectionresult"></select><span id="result-'+i+'" class="result">&nbsp;</span></p></div>')) 
      .append($('<div class="info-line"><label>Product</label><p><select id="selectionresult2-'+i+'" name="selectionresult2-'+i+'" class="selectionresult2"></select><span id="result2-'+i+'" class="result2">&nbsp;</span></p></div>')) 
      .append($('<a class="remove" href="#add-product" id="remove-product'+i+'"><img src="<?php echo base_url();?>img/remove-product.jpg" alt="" />Remove Product</a>')) 
      .appendTo("#products"); 

     // START OF ADDITIONAL PRODUCT DROP DOWNS 
     $("#selectionresult-" + i).hide(); 
     $("#selectionresult2-" + i).hide(); 

     $("#selection-" + i).change(function() { 

      $(this).next(".selectionresult").hide(); 
      $(this).next(".selectionresult2").hide(); 
      $("#result-" + i).html('Retrieving ...'); 
      $.ajax({ 
       type: "POST", 
       data: "data=" + $(this).val(), 
       url: "<?php echo base_url();?>dropdown.php", 
       success: function (msg) { 
        if (msg != '') { 
         $("#selectionresult-" + i).html(msg).show(); 
         $("#result-" + i).html(''); 
        } 
        else { 
         $("#result-" + i).html('<em>No item result</em>'); 
        } 
       } 
      }); 

     }); 
     $("#selectionresult-" + i).change(function() { 
      $(this).next(".selectionresult2").hide(); 
      $("#result2-" + i).html('Retrieving ...'); 
      $.ajax({ 
       type: "POST", 
       data: "data=" + $(this).val(), 
       url: "<?php echo base_url();?>dropdown.php", 
       success: function (msg) { 
        if (msg != '') { 
         $("#selectionresult2-" + i).html(msg).show(); 
         $("#result2-" + i).html(''); 
        } 
        else { 
         $("#result2-" + i).html('<em>No item result</em>'); 
        } 
       } 
      }); 
     }); 

    // End closure. Executes the closure function, passing in the 
    // current value of "i" 
    })(i); 
}); 

编辑:

为了解释发生了什么,在JavaScript中,传递给(或创建于)函数体的变量对于该函数是本地的,并且它们会持续存在。

我上面正在做的是创建一个函数,接受一个参数。在这里,我将更改名称参数的或许更清楚:

function(inner_i) { 
    // create your element with the new local variable "inner_i" 
} 

...但我也调用,一旦我创建它的功能:

(function(inner_i) { 
    // create your element with the new local variable "inner_i" 
})(i) 
// ^------- call the function, passing in the "i" from your loop. 

语法看起来有点奇怪,但它只是一种调用刚刚创建的函数的方法。

这将是一样的做:

function myNewFunction(inner_i) { 
    // creates your element with the new local variable "inner_i" 
} 

myNewFunction(i); // Call the function we just created above, 
        // and pass the "i" from the loop into it 
+0

无法得到这个工作,可能是因为我没有使用for循环。 – Carson 2010-08-17 13:17:36

+0

@Carson - 你会以同样的方式使用它。我会在顶部替换我的答案来演示。为了简单起见,即使选择器不需要它,我也只是将(几乎)* *整个*代码封装在闭包中。请注意,'i ++'将在闭包之外。 – user113716 2010-08-17 13:26:20

+0

@Carson - 我更新我的答案。要了解发生了什么,请阅读提供解释的代码注释。如果您有任何问题,请随时在这里提问。关闭可能是JavaScript的最佳功能之一,所以在某些时候,理解一些关于它们是值得的。 :o) – user113716 2010-08-17 13:45:35

0

使用一个独立的变量存储在索引中,使用循环来添加到它。

粗略地说,带循环的函数(不管是否用索引号调用另一个函数都是不相关的),但这样你可以得到存储的索引值,并使用你的循环,所以没有重复。

var uniqueIndex = 0; 

function functionWithLoop(x) 
{ 
    for (i=0; i<x; i++) 
    { 
     uniqueIndex++; 
     createNewDivFunction(uniqueIndex); 
    } 
} 
0

从我能理解div1中的元素是指对方而不是div2中的元素。问题是,它们如何互相引用?如果是通过事件,例如一个文本框的onchange事件,那么你就可以做到以下几点:

var MAX = 10; 
for (var i = 0; i < MAX; i++) { 
    // Create textbox 
    $("<input type='text'>").attr("name", "slave" + i); 
    // Create a second textbox that, when changed, takes it's value, 
    // makes it uppercase, and copies it to the first one 
    $("<input type='text'>").attr("name", "master" + i) 
    .change(
     (function(i) { 
      function() { 
       $("input[name=slave" + i + "]").text($(this).text()); 
      } 
     })(i) 
    ); 
} 

它的作用是创建捕获内本身的i价值的临时范围:

 (function(i) { 
      function() { 
       // the value of i is frozen in time within here 
      } 
     })(i) 
0

实际上,更简单的答案是将整数作为值存储到您创建的每个元素。让您摆脱封闭困扰,并且更易于维护。在你的循环只是做:

newElement.data("myIndex", i); 

,并检索再次索引:

newElement.data("myIndex"); 

或者,如果事件处理程序中:

$(this).data("myIndex"); 
+0

这看起来像我正在寻找的只是不知道该怎么做。今天晚些时候我会试一试。谢谢 – Carson 2010-08-16 14:43:00

+0

@Carson - 请记住,与使用闭包相比,'.data()'是一个缓慢的操作。如果你只是需要引用“我”的价值,这会起作用,但我会说这是过度的。 – user113716 2010-08-16 15:45:46