【问题标题】:dynamically added dom-elements not responding to jQuery-function动态添加的 dom 元素不响应 jQuery 函数
【发布时间】:2017-02-11 13:32:55
【问题描述】:

考虑以下代码:

            $(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>

程序的作用如下:

用户可以通过给出一个 x 值和一个 y 值来选择一个字段。在该字段中,显示来自带有“文本”标签的输入字段的内容。 - 这部分程序运行良好。

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

唯一不起作用的功能如下: 如果用户点击表格中的一个非空字段,表格的内容应该会回到它的自然(空)状态。

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

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

这段代码基本意思是: 如果用户点击表格中的任何框(“td”),该框的内容应该会消失。

这或多或少是代码中最简单的部分。但这也是行不通的一方面。更准确地说:它适用于原始框,但不适用于添加的任何框。 - 我不明白它为什么会这样。

【问题讨论】:

标签: javascript jquery dom


【解决方案1】:

如果您正在向 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 中的元素连接必要的事件处理程序。

【讨论】:

  • 完美!非常感谢您的解释...之前不知道
  • 将点击处理程序附加到整个表格可以实现相同的目标。即使添加了新的行和单元格,处理程序也在表格上,因此单击这些新单元格仍然会产生预期的效果。
【解决方案2】:

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

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

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

ev.currentTarget 属性将是 &lt;table&gt; 元素,因为这是事件处理程序注册到的元素,但 ev.target 属性将是您要查找的 &lt;td&gt; 元素。

这里有一个JSFiddle 供您试验。

【讨论】:

    【解决方案3】:

    嘿,这就是我认为的答案,

    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";
          });
        })();
    
      };
    

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

    【讨论】:

    • 大部分内容,它不完整,但我认为这部分可能是关键部分,我用香草完成了这一切,又好又干净
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-22
    • 2019-05-24
    • 1970-01-01
    • 2016-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多