2010-08-16 201 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