动态添加的dom元素不响应jQuery函数



考虑以下代码:

$(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"),则该框的内容应消失。

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

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

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

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

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

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

这里有一个JSFiddle可以进行实验。

嘿,这是我认为的答案,

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

编辑:我甚至没有完全回答这个问题。您可能想将事件侦听器附加到最近的非动态父级,这样点击事件就会弹出,您可以捕捉到这一点,请检查新添加代码注释下的代码。

最新更新