动态添加的dom-elements不响应jQuery-function

时间:2017-02-09 01:58:51

标签: javascript jquery dom

请考虑以下代码:



            $(document).ready(function(){

                var table1 = $("table").eq(0);
                var row_list;
                var rows;
                var x;
                var y;

                $("#mybutton").click(function(){

                    row_list = table1.find("tr");
                    rows = row_list.length;
                    x = $("#field_x").val();
                    y = $("#field_y").val();

                    if(x>rows || y>rows){

                         var num;   
                         if(x>y) num=x;
                         else num=y;
                         var n = num-rows;    
                         var row; table1.find("tr").eq(0).clone();

                         while(1){
                            row = table1.find("tr").eq(0).clone();
                            table1.append(row);
                            n--;
                            if(n===0) break;
                         }

                         n = num-rows;    
                         var td;

                         while(1){
                            td = table1.find("td").eq(0).clone();
                            table1.find("tr").append(td);
                            n--;
                            if(n===0) break;
                         }

                    }

                    var text = $("#text").val();
                    var css = $("#css").val();
                    $("table:eq(0) tr:eq(" + (x-1) + ") td:eq(" + (y-1) + ")").text(text).css("color", css);

                });


                table1.find("td").click(function(){
                    $(this).html("");
                });


            });

            * {
                font: 14px normal Arial, sans-serif;
                color: #000000;
            }
            table {
                margin: 50px auto;
            }
            table, td {
                border: 1px solid #aaa;
                border-collapse: collapse;
            }
            th {
                padding: 10px;
                font-weight: bold;
            }
            td {
                background-color: #eeeeee;
                width: 80px;
                height: 80px;
            }
            table:first-child tr td {
                cursor: pointer;
            }
            td[colspan="4"]{
                text-align:center;
            }

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
            <tbody>
                <tr>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>
                <tr>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>
                <tr>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>
                <tr>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>
            </tbody>
        </table>
        <table>
            <thead>
                <tr>
                    <th colspan="4">Fill a field:</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>Text: <br/><input type="text" id="text" value=""></td>
                    <td>Field X: <br/><input type="text" id="field_x" value=""></td>
                    <td>Field Y: <br/><input type="text" id="field_y" value=""></td>
                    <td>CSS: <br/><input type="text" id="css" value=""></td>
                </tr>
                <tr>
                    <td colspan="4"><button id="mybutton">Fill</button></td>
                </tr>
            </tbody>
        </table>
&#13;
&#13;
&#13;

该计划的作用如下:

用户可以通过给出x值和y值来选择字段。在此字段中,输入字段中的内容带有标签&#34; Text&#34;被展示。 - 这部分程序运行正常。

如果用户选择的x值或y值大于当前行数(列),则添加行和列,直到行/列的数量等于x-中的值(或y-)字段。 - 这部分程序也可以正常工作。

唯一不起作用的功能如下: 如果用户单击表中的一个非空字段,则表的内容应该返回其自然(空)状态。

为此,代码中添加了以下函数(请参阅代码的javascript部分中的最后几行):

table1.find("td").click(function(){
         $(this).html("");
});

这段代码基本上意味着: 如果用户点击表格中的任何框(&#34; td&#34;),此框的内容将消失。

这或多或少是代码中最简单的部分。但它也是一个不起作用的方面。更确切地说:它适用于原始盒子,但它不适用于任何添加的盒子。 - 我不明白为什么它表现那样。

3 个答案:

答案 0 :(得分:4)

如果要动态地向DOM添加元素并希望将事件附加到它们,则应考虑通过on()函数使用事件委派:

// This will wire up a click event for any current AND future 'td' elements
$(table1).on('click', 'td', function(){
     $(this).html("");
});

单独使用click()只会为调用该函数时存在于DOM中的元素连接必要的事件处理程序。

答案 1 :(得分:1)

您在用户有机会输入任何数据之前分配事件处理程序。这意味着如果添加了一个额外的行或列,则需要手动添加新的<td> s事件处理程序。

或者,您可以向整个表添加单击处理程序:

table1.click(function (ev) { $(ev.target).html(''); }

ev.currentTarget属性将是<table>元素,因为这是事件处理程序注册的元素,但ev.target属性将是<td>元素。寻找。

这是一个JSFiddle来试验。

答案 2 :(得分:1)

嘿,在这里,我认为答案可能是什么,

HTML文件:

<!DOCTYPE html>
<html lang="de-DE">
    <head>
        <meta charset="UTF-8" />
        <style>
            * {
                font: 14px normal Arial, sans-serif;
                color: #000000;
            }
            table {
                margin: 50px auto;
            }
            table, td {
                border: 1px solid #aaa;
                border-collapse: collapse;
            }
            th {
                padding: 10px;
                font-weight: bold;
            }
            td {
                background-color: #eeeeee;
                width: 80px;
                height: 80px;
            }
            table:first-child tr td {
                cursor: pointer;
            }
            td[colspan="4"]{
                text-align:center;
            }

            .pre-height {
                min-height: 80px;
            }
        </style>
    </head>
    <body>
        <table>
            <tbody>
                <tr>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>
                <tr>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>
                <tr>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>
                <tr>
                    <td class="pre-height"></td>
                    <td class="pre-height"></td>
                    <td class="pre-height"></td>
                    <td class="pre-height"></td>
                </tr>
            </tbody>
        </table>
        <table>
            <thead>
                <tr>
                    <th colspan="4">Fill a field:</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>Text: <br/><input type="text" id="text" value=""></td>
                    <td>Field X: <br/><input type="text" id="field_x" value=""></td>
                    <td>Field Y: <br/><input type="text" id="field_y" value=""></td>
                    <td>CSS: <br/><input type="text" id="css" value=""></td>
                </tr>
                <tr>
                    <td colspan="4"><button id="myButton">Fill</button></td>
                </tr>
            </tbody>
        </table>

        <script src="jquery.min.js"></script>
        <script src="jack.js"></script>

    </body>
</html>

JACK.JS文件:

window.onload = function() {

'use strict';

/**
 * Appends 'n' number of rows to the table body.
 *
 * @param {Number} n - Number of rows to make.
 */
var makeRows = function(n) {
    let tbody= document.getElementsByTagName("table")[0].getElementsByTagName("tbody")[0],
        tr = document.querySelector("table:first-of-type tbody tr");

    for (let i = 0; i < n; i++) {
        let row = Node.prototype.cloneNode.call(tr, true);
        tbody.appendChild(row);
    }
};

/**
 * Appends 'n' number of cells to each row.
 *
 * @param {Number} n - Number of cells to add to each row.
 */
var makeColumns = function(n) {
    let addNCells = (function(n, row) {
        for (let i = 0; i < n; i++) {
            let cell = Node.prototype.cloneNode.call(td, true); 
            row.appendChild(cell);
        }
    }).bind(null, n);

    let tbody= document.getElementsByTagName("table")[0].getElementsByTagName("tbody")[0],
        td = document.querySelector("table:first-of-type tbody tr td"),
        rows = document.querySelectorAll("table:first-of-type tbody tr");

    rows.forEach(function(row) {
        addNCells(row);
    });
};



    document.getElementById("myButton").addEventListener("click", () => {
        let x = document.getElementById("field_x").value,
            y = document.getElementById("field_y").value;

        makeColumns(x);
        makeRows(y);
    });


    /**
     * Newly added code
     */
    (function() {
      let table = document.querySelector("table");
      // We will add event listener to table.
      table.addEventListener("click", (e) => {
          e.target.innerHTML = "";
          e.target.style.backgroundColor = "orange";
      });
    })();

  };

编辑:我甚至没有完全回答这个问题。您可能希望将事件侦听器附加到最近的非动态父级,以便单击事件将冒出来并且您可以捕获它,检查注释新添加的代码下的代码。