我最近开始学习Javascript。我目前正在开展一些项目,但遇到了一个问题。我正在制作联系人管理员页面,其想法是用户输入姓名,电子邮件和电话号码,这些号码将显示在下面动态创建的HTML表格中。有三个按钮。第一个按钮保存信息,第二个按钮清除新用户的输入字段,第三个删除localStorage信息。单击表中的行时,该行的信息将显示在上面的输入字段中。当你点击HTML表格中的一行时,一切正常,但当我点击使用JavaScript创建的表格中的行时,它不起作用。两个表都具有相同的结构,id和#和class,但另一个表不起作用。 信息表单Javascript显示在dvcontainer div。
中这是代码
(function (){
var Person = {
Name: "",
Email: "",
MobileNo: ""
};
var applogic = {
clearuielements: function () {
var inputs = document.getElementsByClassName("c1");
for (i = 0; i < inputs.length; i++) {
inputs[i].value = "";
}
},
saveitem: function () {
var lscount = localStorage.length;
var inputs = document.getElementsByClassName("c1");
Person.Name = inputs[0].value;
Person.Email = inputs[1].value;
Person.MobileNo = inputs[2].value;
localStorage.setItem("Person_" + lscount, JSON.stringify(Person));
location.reload();
},
loaddata: function () {
var datacount = localStorage.length;
if (datacount > 0) {
var render = "<table id='t_id' border='1'>";
render += "<tr><th>Name</th><th>Email</th><th>Phone</th></tr>";
for (i = 0; i < datacount; i++) {
var key = localStorage.key(i);
var person = localStorage.getItem(key);
var data = JSON.parse(person);
render += "<tr><td class='row_s edit_row'>" + data.Name + "</td>";
render += "<td class='row_t'>" + data.Email + "</td>";
render += "<td class='row_d'>" + data.MobileNo + "</td></tr>";
}
render+="</table>";
dvcontainer.innerHTML = render;
}
},
clearstorage: function () {
var storagecount = localStorage.length;
if (storagecount > 0) {
for (i = 0; i < storagecount; i++) {
localStorage.clear();
}
}
window.location.reload();
}
};
var btnsave = document.getElementById('btnsave');
btnsave.addEventListener('click', applogic.saveitem, false);
var btnclear = document.getElementById('btnclear');
btnclear.addEventListener('click', applogic.clearuielements, false);
var btnclearstorage = document.getElementById('btnclearstorage');
btnclearstorage.addEventListener('click', applogic.clearstorage, false);
window.onload = function () {
applogic.loaddata();
};
})();
var edit_row = document.querySelectorAll('#t_id .edit_row');
for(var i=0; i<edit_row.length; i++) {
edit_row[i].addEventListener('click', function(e){
var tr_parent = this.parentNode;
document.getElementById('e_site').value = tr_parent.querySelector('.row_s').innerHTML;
document.getElementById('e_title').value = tr_parent.querySelector('.row_t').innerHTML;
document.getElementById('e_desc').value = tr_parent.querySelector('.row_d').innerHTML;
}, false);
}
&#13;
<!DOCTYPE html>
<html>
<head>
<title>nesto</title>
</head>
<body>
<form action="#" method="post" id="edit_form">
Person Name:<input name="e_site" id="e_site" type="text" class="c1" /><br/>
Email:<input name="e_title" id="e_title" type="text" class="c1" /><br/>
Mobile No:<input name="e_desc" id="e_desc" type="text" class="c1"/><br/>
</form>
<td><input id="btnsave" type="button" value="Save" /></td>
<td><input id="btnclear" type="button" value="Clear" /></td>
<td><input id="btnclearstorage" type="button" value="Clear Storage" /></td>
<div id="dvcontainer"></div>
<!--
<table id="t_id" border="1">
<tr>
<td class="row_s edit_row">yyyy</td>
<td class="row_t">yyyy</td>
<td class="row_d">yyyyy</td>
</tr>
</table>
-->
<script type="text/javascript" src="funkcije.js"></script>
</body>
</html>
&#13;
答案 0 :(得分:0)
渲染表时需要添加绑定。一种方法是将代码末尾的绑定循环移动到loaddata
函数中。
这样的事情会起作用:
loaddata: function () {
var datacount = localStorage.length;
if (datacount > 0) {
var render = "<table id='t_id' border='1'>";
render += "<tr><th>Name</th><th>Email</th><th>Phone</th></tr>";
for (i = 0; i < datacount; i++) {
var key = localStorage.key(i);
var person = localStorage.getItem(key);
var data = JSON.parse(person);
render += "<tr><td class='row_s edit_row'>" + data.Name + "</td>";
render += "<td class='row_t'>" + data.Email + "</td>";
render += "<td class='row_d'>" + data.MobileNo + "</td></tr>";
}
render+="</table>";
dvcontainer.innerHTML = render;
//add bindings
var edit_row = document.querySelectorAll('#t_id .edit_row');
for(var i=0; i<edit_row.length; i++) {
edit_row[i].addEventListener('click', function(e){
var tr_parent = this.parentNode;
document.getElementById('e_site').value = tr_parent.querySelector('.row_s').innerHTML;
document.getElementById('e_title').value = tr_parent.querySelector('.row_t').innerHTML;
document.getElementById('e_desc').value = tr_parent.querySelector('.row_d').innerHTML;
}, false);
}
}
请参阅此JS小提琴中的完整示例:https://jsfiddle.net/9n8ecmj8/
希望有所帮助!
答案 1 :(得分:0)
如果向DOM添加新元素并希望它们具有事件侦听器,则需要在添加后将元素添加到元素中。
看起来您正在将click事件侦听器添加到脚本加载时存在的元素,但不会向动态创建的元素添加任何元素。设置单击侦听器的代码在loaddata函数绑定到window.onload之前运行。
答案 2 :(得分:0)
您编写的用于添加侦听器的for循环在您首次加载JavaScript时执行,早在您创建任何新表格单元格之前。要在DOM元素上注册事件侦听器,该元素必须首先存在,对吧? :)
您需要做的是称为事件委派。基本上,在JavaScript运行之前,在网页上存在的DOM元素上连接一个事件侦听器。此DOM元素必须是目标元素的父元素。
在您的情况下,ID “dvcontainer”的div会很好,因为您在其中呈现表格。首先,我们将选择它:
var myContainer = document.querySelector('#dvcontainer');
myContainer.addEventListener('click', function(e) {
//...
};
如果我们向 myContainer 添加一个事件监听器,它将在任何点击时调用点击处理函数到整个div 。我们知道 e.target 选择了被点击的元素,但是对于名为匹配的元素有一个有用的方法,它会告诉我们所选元素是否与选择器字符串匹配(例如“#”容器“,”。username“,甚至”h2“)。
什么是你的桌子的好选择器?为了简单起见,让我们使用“td”处理任何表格单元&lt;获得点击的td&gt; 。这是解决问题的有效方法(用此替换你的for循环):
var myContainer = document.querySelector('#dvcontainer');
// adds event listener on myContainer
myContainer.addEventListener('click', function(e) {
// if the clicked element exists and is a TD element
if (e.target && e.target.matches('td')) {
// your code from your original for loop
var tr_parent = e.target.parentNode;
document.getElementById('e_site').value = tr_parent.querySelector('.row_s').innerHTML;
document.getElementById('e_title').value = tr_parent.querySelector('.row_t').innerHTML;
document.getElementById('e_desc').value = tr_parent.querySelector('.row_d').innerHTML;
}
}, false);
这种方法的好处是你只需要设置一次事件监听器。无论您使用JS动态创建一个,两个还是一千个新DOM元素,它们都将“继承”相同的侦听器和处理程序,而无需动态注册每个元素。
希望这对你有所帮助!
更多信息:
Vanilla JS事件代表团:https://davidwalsh.name/event-delegate
element.matches():https://developer.mozilla.org/en-US/docs/Web/API/Element/matches