国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

javascript - How to traverse the functions and contents of dynamically added elements
代言
代言 2017-06-12 09:28:08
0
5
909

As shown in the figure: The function to be realized is to click the add button at the top and dynamically add table rows at the bottom, and then the content in each row is traversed from the object.
Then I only have the lines written in the first html that have content and functions.
The row that comes out after clicking the button has no content and no function. (Note: The function refers to my first column and second column, which are the secondary linkage effects)

The following is the code: (I am a novice, and I am not very familiar with jq, so the writing is very messy, and it is a mixture of js and jq =-=, please give me some advice and guidance!)

    <p class="clearfix" style="margin-left:200px;">
    <button class="button2" style="border:1px solid #000">添加</button>
    <form class="clearfix" style="float:left;margin-top:100px;">
        <table id="b" border="1px solid #000">
            <thead>
                <tr class="zzz">
                    <th style="width:141px;">計(jì)算期類型</th>
                    <th style="width:281px;">期間</th>
                    <th style="width:141px;">征收方式</th>
                </tr>
            </thead>
            <tbody id="zType_all">
                <tr>
                    <td>
                        <select id="zType_time"></select>
                    </td>
                    <td>
                        <select id="zType_years" style="float:left;"></select>
                        <select id="month_quarter"></select>
                    </td>
                    <td>
                        <select id="zCollection">
                            <option value="chazhang">查賬征收</option>
                            <option value="heding">核定征收</option>
                        </select>
                    </td>
                </tr>
            </tbody>
        </table>
    </form>
    </p>
//點(diǎn)擊按鈕添加

    $('.button2').on('click',function(){
    var ccc = $('<tr><td><select id="zType_time"></select></td><td><select id="zType_years"></select><select id="month_quarter"></select></td><td><select id="zCollection"><option value="chazhang">查賬征收</option><option value="heding">核定征收</option></select></td></tr>');
    var ddd = $('#zType_all');
    ddd.append(ccc);
    $('#a').css({"background":"white","color":"#000"});
    });



//下面是關(guān)于二級(jí)和三級(jí)聯(lián)動(dòng)的遍歷
//這個(gè)是存儲(chǔ)著option里信息的對(duì)象

    var zType_chose = [
    {
    "name":"年終匯算","types":[
        {"years":"2015年"},
        {"years":"2016年"}
        ]
     },
     {
        "name":"預(yù)繳-月度","types":[
        {"years":"2015年","zType_time1":["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"]},
        {"years":"2016年","zType_time1":["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"]}
        ]
     },
     {
        "name":"預(yù)繳-季度","types":[
        {"years":"2015年","zType_time1":["第一季度","第二季度","第三季度","第四季度"]},
        {"years":"2016年","zType_time1":["第一季度","第二季度","第三季度","第四季度"]}
        ]
     }
     ];

    //下面是我實(shí)現(xiàn)聯(lián)動(dòng)的js代碼
    var zType_time = document.getElementById("zType_time");
    var zType_years = document.getElementById("zType_years");
    var month_quarter = document.getElementById("month_quarter");
    var zType_all = document.getElementById("zType_all");
    zType_time.options[0] = new Option("計(jì)算期類型");
    zType_years.options[0] = new Option("請(qǐng)選擇年");
    month_quarter.options[0] = new Option("請(qǐng)選擇月/季度");
    // 循環(huán)第一步把計(jì)算期類型循環(huán)進(jìn)select
    for (var i = 0; i < zType_chose.length; i++) {
    zType_time.options[zType_time.length] = new Option(zType_chose[i].name);
    // 循環(huán)第二步,把第二列都循環(huán)進(jìn)select
    zType_time.onchange = function(){
    zType_years.options.length = 0;
    month_quarter.options.length = 0;
    zType_years.options[zType_years.length] = new Option("請(qǐng)選擇年");
    month_quarter.options[month_quarter.length] = new Option("請(qǐng)選擇月/季度");
    for (var j = 0; j < zType_chose[zType_time.selectedIndex-1].types.length; j++) {
        zType_years.options[zType_years.length] = new Option(zType_chose[zType_time.selectedIndex-1].types[j].years)
    }
    if(zType_time.options[zType_time.selectedIndex].text == "年終匯算"){
        month_quarter.style.display = "none";
    }else{
        month_quarter.style.display = "inline-block";
    }
    }
    zType_years.onchange = function(){
        month_quarter.options.length = 0;
        month_quarter.options[month_quarter.length] = new Option("請(qǐng)選擇月/季度");
        //循環(huán)另一個(gè)
        for (var k = 0; k < zType_chose[zType_time.selectedIndex-1].types[zType_years.selectedIndex-1].zType_time1.length; k++) {
            month_quarter.options[month_quarter.length] = new Option(zType_chose[zType_time.selectedIndex-1].types[zType_years.selectedIndex-1].zType_time1[k]);  
        };
    }
    };

I think maybe the content should be traversed when creating the rows of the table? But I don’t know how to do it, and what should I do with my function?
Waiting for a big guy online

tell me! Many thanks! urgent!

代言
代言

reply all(5)
typecho

First of all, id can only appear once in a page and is unique. Only class can appear multiple times!

Statement

id is the only attribute, that is, only one corresponding id can appear in a html file, and multiple class can be used;

Requirement realization

The front-end part, from the framework to the functions, can all be solved using design patterns. To put it bluntly, they can all be solved using MVC, as in your example:

  • C -> Entire JS logic;

  • V -> Single line entry;

  • M -> filled data;

You can actually encapsulate this kind of thing with a closure, or make it into a processing class. Such as:

<p class="clearfix" style="margin-left:200px;">
    <button class="button2" style="border:1px solid #000">添加</button>
    <form class="clearfix" style="float:left;margin-top:100px;">
        <table border="1">
            <thead>
                <tr class="zzz">
                    <th width="240">計(jì)算期類型</th>
                    <th width="240">期間</th>
                    <th width="128">征收方式</th>
                </tr>
            </thead>
            <tbody id="zType_all">
            </tbody>
        </table>
    </form>
</p>

Continue to improve the script:

(function($) {
    'use strict';

    /**
     * 組件條目解析
     * 一行即一個(gè)組件條目,該構(gòu)造方法
     * 例:var thisRow = new AppRow();
     * @return {object} 一個(gè) jQuery 對(duì)象
     */
    var AppRow = function() {
        return this.rowParse(this.rowDom());
    };

    // HTML 結(jié)構(gòu)
    AppRow.prototype.rowDom = function() {
        var row = '',
            options = AppRow.typeChose,
            optionYears = options[0].types;

        // 計(jì)算期類型
        row += '<td><select class="type">';
        row += '<option value="-1">請(qǐng)選擇</option>';
        for (var i in options) {
            row += '<option value="' + i + '">' + options[i].name + '</option>';
        }
        row += '</select></td>';

        // 期間
        row += '<td class="types"></td>';

        // 征收方式
        row += '<td><select class="collection">';
        row += '<option value="0">請(qǐng)選擇</option>';
        row += '<option value="1">查賬征收</option>';
        row += '<option value="2">核定征收</option>';
        row += '</select></td>';

        return '<tr>' + row + '</tr>';
    };

    // 解析行結(jié)構(gòu),添加事件
    AppRow.prototype.rowParse = function(row) {
        var $row = $(row),
            $typeTime = $row.find('select.type'),
            $typeTypes = $row.find('.types'),
            optionsData = AppRow.typeChose;

        // 計(jì)算期類型
        $typeTime.on('change.app', $.proxy(function(e) {
            var val = $typeTime[0].value;
            $typeTypes.children().remove();
            $typeTypes.append(this.selectYears(val));
        }, this));

        return $row;
    };

    // 返回年度表單
    AppRow.prototype.selectYears = function(type) {
        var optionYears = AppRow.typeChose[0].types,
            select = '',
            $select = null;

        // 構(gòu)建表單
        select += '<select class="year">';
        select += '<option value="-1">請(qǐng)選擇</option>';
        for (var i in optionYears) {
            select += '<option value="' + i + '">' + optionYears[i].years + '</option>';
        }
        select += '</select>';

        // 構(gòu)建成 jQuery 對(duì)象
        $select = $(select);

        // 事件綁定
        $select.on({
            // 選擇事件
            'change.app': $.proxy(function(e) {
                var val = $select[0].value,
                    $sub = $select.next('.sub');

                if (type <= 0) {
                    // 年終匯算無后續(xù)表單
                    return;
                }

                if (val === -1) {
                    // 未選擇,則移除后續(xù)表單
                    $select.nextAll().remove();
                    return;
                }

                // 創(chuàng)建或或初始化后續(xù)表單
                if (!$sub.get(0)) {
                    // 表單不存在則創(chuàng)建
                    $select.after(this.selectSub(type, val));
                }
                $sub.trigger('reset.app');
            }, this),

            // 重置表單
            'reset.app': $.proxy(function(e) {
                $select.find('option').prop('selected', false)
                    .eq(0)
                    .prop('selected', true);
            })
        });

        return $select;
    };

    // 返回季度或月份表單
    AppRow.prototype.selectSub = function(type, year) {
        var optionData = AppRow.typeChose[type].types[year].zType_time1,
            select = '',
            $select = null;

        if (!optionData) {
            // 無數(shù)據(jù)
            return;
        }

        // 構(gòu)建表單
        select += '<select class="sub">';
        select += '<option value="-1">請(qǐng)選擇</option>';
        for (var i in optionData) {
            select += '<option value="' + i + '">' + optionData[i] + '</option>';
        }
        select += '</select>';
        $select = $(select);

        // 事件綁定
        $select.on({
            // 重置表單
            'reset.app': $.proxy(function(e) {
                $select.find('option').prop('selected', false)
                    .eq(0)
                    .prop('selected', true);
            })
        });

        return $select;
    };

    // 聯(lián)動(dòng)數(shù)據(jù) - zType_chose
    AppRow.typeChose = [{
        "name": "年終匯算",
        "types": [{
            "years": "2015年"
        }, {
            "years": "2016年"
        }]
    }, {
        "name": "預(yù)繳-月度",
        "types": [{
            "years": "2015年",
            "zType_time1": ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"]
        }, {
            "years": "2016年",
            "zType_time1": ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"]
        }]
    }, {
        "name": "預(yù)繳-季度",
        "types": [{
            "years": "2015年",
            "zType_time1": ["第一季度", "第二季度", "第三季度", "第四季度"]
        }, {
            "years": "2016年",
            "zType_time1": ["第一季度", "第二季度", "第三季度", "第四季度"]
        }]
    }];

    AppRow.VERSION = '1.0.0';

    // ===========================================

    // 添加按鈕事件綁定
    var $addBtn = $('.button2'),
        $rowList = $('#zType_all');

    // 點(diǎn)擊添加
    $addBtn.on('click.app', function(e) {
        // 或直接添加實(shí)例
        $rowList.append(new AppRow());
    });

})(jQuery);

Explanation

  • Create a constructor to generate a structure with interactive encapsulation effect - component;

  • Add a series of methods to the component and create logic inside;

  • Closure encapsulation refers to only taking effect in (function($){ /*code*/ })(jQuery);;

  • $.fn.remove can ensure the security of the data on the page. Do not use $.fn.hide;

  • You can also use AppRow.prototype.delete() to extend delete operations, etc.;

  • If you need to use name for data submission, you need to use the format of name="row[index][name]", such as: name="row[1]['type']", name="row[1]['year']"、name="row[1]['sub']";

Final effect:

Online effect

https://jsfiddle.net/kxjyo7fp...

某草草

Put the code for traversing the data in the method where you click to add a row. The specific coordination is how to add a row and traverse one. You have to implement this yourself. I didn't look into it carefully. You are now a bit like a dynamically added element. You bind the event, and the result is bound in the HTML written, but the added element is not bound to the event

學(xué)霸

It is recommended to use the ui library directly. For jquery, you can choose easyui / bootstrap table

學(xué)習(xí)ing

Event binding will be successfully bound after the page rendering is completed, and will not be automatically bound afterwards. That is, nodes added after the page is rendered cannot be bound. What we are talking about here is $('.a').click (...) This is a similar method because when it is compiled for the first time, an event will be bound to the class A on the page. If you dynamically condition several nodes with class a in JS, then adding them later will have no effect. , because the node added later does not exist when binding for the first time.
The solution is to use the on() method. For example, $('body').on('click','.a',fun(){}) This method is fine, because the body tag will exist no matter when. Therefore, there will be no situation where the node cannot be found and cannot be bound.
Of course, you can also write the function on the node yourself, but this is not recommended.

小葫蘆

I rewrote part of the script to generate DOM using jQuery. For speed, I used some ES6 syntax. But the function is not completed yet

https://jsfiddle.net/jrhju549/1/

Then when I was thinking about cascading this part of things, I found a problem (about data):

From the data point of view, the optional data for monthly payment and quarter are the same no matter what year it is. Month is 12 months and quarter is 4 quarters. Then these data are actually fixed and can be written directly in HTML. In this way, when generating new rows, you only need to clone them first and then handle the details, which is much simpler.

However, another possibility cannot be ruled out, that is, your options are different every year. For example, 2015 is 12 months, 2016 is 8 months... (Of course, the possibility of this situation is very low), in this case, the select can be dynamically generated based on this data. Then before dynamically generating select, you need to use a findXxxx function to find the data that the corresponding option list needs to use - this process will of course be much more complicated.

Looking at the current progress, here are a few main points

Modular processing

Don’t think of doing everything in one function, split it up. For example, I initially split createRow and createSelect in the code. Among them, createSelect is highly reusable

// 創(chuàng)建 select,items 是數(shù)據(jù) map 是名稱映射表
// 如果名稱本來就是按 value 和 text 來命名,就不需要映射表
function createSelect(items, map = {}) {
    const value = map.value || "name";
    const text = map.text || "text";
    const $options = items
        .map(t => $("<option>").prop({ value: t[value] }).text(t[text] || ""));
    return $("<select>").append(...$options);
}
// 創(chuàng)建一個(gè) tr,含 td 和初始化的 select
function createRow() {
    var $tr = $("<tr>");
    var $tds = Array.from(Array(3))
        .map(() => $("<td>"));

    createSelect(types).appendTo($tds[0]);

    createSelect([
        { value: "chazhang", text: "查賬征收" },
        { value: "heding", text: "核定征收" }
    ]).appendTo($tds[2]);

    return $tr.append(...$tds);
}

Organize the data first

Because the DOM structure is generated based on data, the data is very important. The intuitive way is to search for the data at the same time, but this way the code looks messy. Therefore, it is generally recommended to organize and prepare the corresponding data first, and then generate DOM based on the organized data

For example, types is extracted from zType_chose first

// 生成類型數(shù)據(jù)
var types = [{ text: "計(jì)算機(jī)期類型" }]
    .concat(zType_chose.map(t => ({
        value: t.name,
        text: t.name
    })));

When sorting list data, map, filter and reduce are basically standard (for more complex situations, you can consider RxJs)

You have changed id to class, which is good, clearing the way for later use $.fn.close(). Since I don't have much time to go further, I'll leave the question to you: consider defining select in HTML, and then handle the details (such as hiding) in code. If the select still needs to be defined based on data, you can fill in all the first select at the beginning to facilitate cloning later - of course in this case, the process of perfecting tr is encapsulated in a function, and you don't even need to clone. You can also create tr directly.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template