javascript - init()为啥无法给动态生成的btn加点击事件?

查看:92
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆