簡體   English   中英

如何對動態添加的元素執行動態操作?

[英]How can I perform dynamic operations on dynamically added elements?

我的目標:

  • 使用JS / Jquery動態填寫'performer-payments'表
  • 對於表中的每個(動態添加的)行,其中一個數據單元格包含一個下拉框。
  • 當選擇某個選項時,此下拉框應該顯示另一個下拉框(在同一個單元格中)。 否則,第二個下拉列表應該是不可見的。
  • 在其他地方,我通過toggleVisible函數完成隱藏/顯示動態,它只是添加了由css標記的自定義類來隱藏或顯示元素。

相關代碼:

我要填充的表格:

<table id='performer-payments' class='performer-profile payments-table'>              
    <tr>
        <th> Period </th>                                                             
        <th> Amount </th>                                                             
        <th> Paid? </th>                                                              
    </tr>
</table>

填充表格的代碼:

for (period in data['Performers'][performer]['Payments']) {
    var amount = utils.calcPerformerCut(data, performer, period);                 
    var row = "<tr>";
    row += "<td> " + period + " </td>";
    row += "<td> " + amount + " $ </td>";
    row += "<td>";
    row += "<div class='performer-profile payment-status'>";
    row += data['Performers'][performer]['Payments'][period];
    row += "</div>";
    row += "<select id='payment-status-" + performer + "-" + period + "' class='perfomer-profile hidden-onload displayNone payment-status-menu'>";
    row += "<option value='paid'>Paid</option>";
    row += "<option value='unpaid'>Unpaid</option>";
    row += "<option value='transfer'>Transfer to...</option>";
    row += "</select>";
    row += "<select id='payment-transfer-period-" + performer + "-" + period + "' class='performer-profile hidden-onload displayNone payment-period-menu'>";
    for (var i=0; i < data['Periods'].length; i++) {                              
        row += "<option value='" + period + "'>" + period + '</option>';          
    }
    row += "</select>";
    row += "</td>";
    row += "</tr>";

    $('#performer-payments').append(row);
    $('#performer-payments').on('change', {perf: performer, per: period}, function (even) {
        if (even.target.value == 'transfer') {
            utils.toggleVisible($('#payment-transfer-period-' + even.data.perf + '-' + even.data.per), true);
        } else {
            utils.toggleVisible($('#payment-transfer-period-' + even.data.perf + '-' + even.data.per), false);
        }
    });
}

供參考,切換可見性的代碼:

exports.toggleVisible = function (selector, visible) {
    if (visible) {
        selector.removeClass('displayNone').addClass('displayBlock');
    } else {
        selector.removeClass('displayBlock').addClass('displayNone');
    }
}

這個(至少)有兩個問題:

  • 即使在第一個選擇框中選擇了“轉移”選項,也不會顯示#payment-transfer-period -...選擇框。 從調試工作來看,在我看來,#payment-transfer-period- ..由於某種原因可能還不是一個有效的對象,或類似的東西。
  • (顯然,真的),on-change事件被觸發N次(N =周期數),因為我只是告訴程序在表中的某些內容發生變化時觸發。 我希望它只觸發相關的下拉列表,但當我嘗試將#payment-status -...作為選擇器添加到.on()函數時,它使它永遠不會觸發。

注意:我歡迎對此提出反饋 - 我是一名經驗豐富的程序員,但對HTML / JS / Jquery的經驗很少。 此外,我決定不使用模板進行這個項目,因為我正在嘗試學習基礎知識,所以如果你從看到我動態'添加行到表的方式得到胰腺炎,我道歉,但它是部分故意的。

除此之外,如果此處不清楚,請詢問澄清。

編輯 :這是數據結構的相關部分:

data = {
    'Performers': {
        'Dira Klaggen': {
            'Payments': {
                'Q1': 'Paid',
                'Q2': 'Paid',
                'Q3': 'Unpaid'
            },
        },
        'Holden Bolden': {
            'Payments': {
                'Q2': 'Transferred to Q3',
                'Q3': 'Unpaid'
            }
        },
        'Manny Joe': {
            'Payments': {
                'Q1': 'Paid',
                'Q2': 'Unpaid',
                'Q3': 'Unpaid',
            }
        }
    },
    'Periods': [
        'Q1',
        'Q2',
        'Q3'
    ]
}  

您沒有將change處理程序附加到右側元素。 我應該是行中的第一個select ...而不是整個table

試試這個change處理程序

$('#performer-payments').find('#payment-status-' + performer + '-' + period).on('change', function(){
  if ($(this).val() == 'transfer') {
    $(this).next('select').show();
  } else {
    $(this).next('select').hide();
  }
});


第二種方法:
您可以通過使用類而不是第一個select的“復雜”唯一id來簡化它。

假設你使用的class “支付狀態”:

處理程序將是:

 $('#performer-payments').on('change', '.payment-status', function(){ if ($(this).val() == 'transfer') { $(this).next('select').show(); } else { $(this).next('select').hide(); } }); 

並且此處理程序可以不在行追加循環中,因為它使用委托

讓我們通過執行以下操作來清理代碼:

  1. 使用類而不是丑陋的ID。

  2. 使用數據屬性或隱藏的輸入字段來保存額外信息。

  3. 使用事件委派來綁定動態創建的元素。 在事件處理器,使用樹遍歷方法來限制基於當前元素的搜索范圍this

讓我們應用這些東西。

像這樣構建每一行。 {PLACEHOLDER}是您在代碼中放置變量的地方。

<tr>
    <td>{PERIOD}</td>
    <td>{AMOUNT} $ </td>
    <td>
        <div class='performer-profile payment-status'>
            {SOMETHING-RELATING-TO-PERFORMER-PAYMENT-PERIOD}
        </div>
        <!-- remove ID -->
        <!-- store performer and period in data-attributes -->
        <select class='perfomer-profile hidden-onload displayNone payment-status-menu' data-performer='{PERFORMER}' data-period='{PERIOD}'>
            <option value='paid'>Paid</option>
            <option value='unpaid'>Unpaid</option>
            <option value='transfer'>Transfer to...</option>
        </select>
        <!-- remove ID -->
        <select class='performer-profile hidden-onload displayNone payment-period-menu'>                             
            <option value='{PERIOD}'>{PERIOD}</option>
            <option value='{PERIOD}'>{PERIOD}</option>  
            <option value='{PERIOD}'>{PERIOD}</option>
            <!-- etc -->
        </select>
    </td>
</tr>

在JavaScript中,創建委派的事件處理程序 請注意語法。

$(function () {

    // ...

    for (period in data['Performers'][performer]['Payments']) {
        // build and append row
    }

    // create delegated event handler once and outside FOR loop
    $(document).on('change', '.payment-status-menu', function () {
        // get the current status menu
        var statusMenu = $(this);
        // find its related period menu
        var periodMenu = statusMenu.closest('tr').find('.payment-period-menu');
        // toggle its visibility
        periodMenu.toggle(this.value == 'Transfer');

        // of course, this could be a one-liner
        //$(this).closest('tr').find('.payment-period-menu').toggle(this.value == 'Transfer');
    });

});

看起來你不需要(2.)但是如果你這樣做,在事件處理程序中,使用statusMenu.data('performer')statusMenu.data('period')來獲取它的執行者和周期值。 您也可以執行this.dataset.performerthis.dataset.period

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM