javascript - init()为啥无法给动态生成的btn加点击事件?
本文介绍了javascript - init()为啥无法给动态生成的btn加点击事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
问 题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>task_16</title>
<style>
table {
border-collapse: collapse;
text-align: center;
width: 400px;
}
table, tr, td {
border: 1px solid gray;
}
</style>
</head>
<body>
<div>
<label>城市名称:<input id="api-city-input" type="text"/></label>
<label>空气质量指数:<input id="api-city-value" type="text"/></label>
<button id="add-btn">确认添加</button>
</div>
<table id="api-table">
<!--
<tr>
<td>城市</td><td>空气质量</td><td>操作</td>
</tr>
<tr>
<td>北京</td><td>90</td><td><button>删除</button></td>
</tr>
<tr>
<td>北京</td><td>90</td><td><button>删除</button></td>
</tr>
-->
</table>
<script>
/**
* aqiData,存储用户输入的空气指数数据
* 示例格式:
* aqiData = {
* "北京": 90,
* "上海": 40
* };
*/
var apiData = {};
var otext = getId('api-city-input');
var ovalue = getId('api-city-value');
var otable = getId('api-table');
var obtn = getId('add-btn');
var str = '';
/**
* 从用户输入中获取数据,向aqiData中增加一条数据
* 然后渲染aqi-list列表,增加新增的数据
*/
function addApiData() {
var otext_value = otext.value.trim();
var ovalue_value = ovalue.value.trim();
// if (!otext_value.match(/^[A-Za-z\u4E00-\u9FA5]+$/)) {
// alert("城市名必须为中英文字符!")
// return;
// }
// if (!ovalue_value.match(/^\d+$/)) {
// alert("空气质量指数必须为整数!")
// return;
// }
apiData[otext_value] = ovalue_value;
}
/**
* 渲染aqi-table表格
*/
function renderApiList() {
str = "<tr><td>城市</td><td>空气质量</td><td>操作</td></tr>";
for (var attr in apiData) {
str += ' <tr><td>' + attr + '</td><td>' + apiData[attr] + '</td><td><button>删除</button></td></tr>';
}
otable.innerHTML = '';
otable.innerHTML = attr ? str : "";
}
/**
* 点击add-btn时的处理逻辑
* 获取用户输入,更新数据,并进行页面呈现的更新
*/
function addBtnHandle() {
addApiData();
renderApiList();
}
/**
* 点击各个删除按钮的时候的处理逻辑
* 获取哪个城市数据被删,删除数据,更新表格显示
*/
function delBtnHandle() {
//do sth
var odel = otable.getElementsByTagName('button');
for (var i = 0; i < odel.length; i++) {
odel[i].index = i;
odel[i].onclick = function () {
otable.deleteRow(this.index);
};
}
renderApiList();
}
function init() {
// 在这下面给add-btn绑定一个点击事件,点击时触发addBtnHandle函数
obtn.onclick = addBtnHandle;
// 想办法给aqi-table中的所有删除按钮绑定事件,触发delBtnHandle函数
if (!otable.getElementsByTagName('button').length) {
return;
} else {
var odel = otable.getElementsByTagName('button');
console.log(odel.length);
for (var i = 0; i < odel.length; i++) {
odel[i].onclick = alert(1);
}
}
}
init();
function getId(id) {
return document.getElementById(id);
}
</script>
</body>
</html>
解决方案
init的时候otable.getElementsByTagName('button').length等于0,所以根本绑定不了事件
可以在renderApiList 之后再为按钮添加事件,也可以使用事件委托的方式。
简单来说,就是这么写
document.body.onclick = function(e) {
if(e.target && e.target.nodeName == "button") {
}
});
推荐使用事件委托,这样可以在一开始就绑定事件,特别是如果你要监听的节点特别多,不使用这种方式,就要为每个节点添加事件监听器。选择多个节点共有的父节点,并且是init中就已经创建出的节点。当这个父节点事件响应时,事件监听器会告诉你是从哪个子节点触发并冒泡上来的事件,即可对这个子节点进行操作。
如果还不明白的话,再去搜索下事件冒泡
这篇关于javascript - init()为啥无法给动态生成的btn加点击事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文