html - JavaScript事件代理的触发源如何判定?
迷茫
迷茫 2017-04-10 17:25:05
[JavaScript讨论组]

现在有一个ul里面原本是空的,然后通过ajax请求数据生成许多个li。而每个li都有相关的操作。
这种类型的场景就很适合用事件代理了。
HTML结构如下:

<ul id="ul">
    <li>
        <p>
            <button class="delete"><i classs="fa fa-cross"></i> 删除</button>
            <button class="save"><i classs="fa fa-plus"></i> 添加</button>
        </p>
    </li>
    <li>
        <p>
            <button class="delete"><i classs="fa fa-cross"></i> 删除</button>
            <button class="save"><i classs="fa fa-plus"></i> 添加</button>
        </p>
    </li>
</ul>

现在每个li有几个button。那么我需要在ul上面绑定两个监听器对应两个button的点击事件。

    var ul = document.getElementById("ul");
    function  delete_li( event ){
        //具体实现
    }
    function append_li( event ){
        //具体实现
    }
    ul.addEventListener("click" , delete_li);
    ul.addEventListener("click" , append_li);

问题来了,不同的button需要触发不同的函数。如果是单纯的button那就很好办判定一下event .target的class就好。
现在为了美观 里面是一个icon buttonevent .target就可以使是button标签也可能是i标签。
我知道通过if的或条件可以枚举这两种情况。但是看起来太不优雅了。也许button标签里面的结构还可能会更复杂。总不可能再来枚举吧。

有没有更好的解决方案?

我说的更好方案是即便html结构从

<button class="delete"><i classs="fa fa-cross"></i> 删除</button>

变成下面这样,甚至更复杂。我希望我尽量不用改js代码

<button class="delete">
    <i classs="fa fa-cross"></i>
    <p><span>删除</span></p>
</button>
迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

全部回复(6)
天蓬老师

貌似很复杂。现在的问题就是使用事件代理中,如果点击的元素(此问题中的i)是我们可以轻易获得的节点(此问题中的button)的后代怎么办?
其实只要判断下i是不是button的后代元素就行了。诚如题主所说,button里面再复杂,只要看他是不是button的后代就行了,是的话就照样执行
伪代码如下

html:
<ul>
  <li><button class='delete'><i class='fa sdf'></i></button></li>
</ul>
var btn=document.getElementByTagName('button')[0];
var nodes=btn.getElementsByTagName('*');//button元素所有的后代元素的集合
var i=btn.getElementByTagName('i')[0];
ul.addEventListener('click',function(e){
  var event=e||window.event;
  var index=[].indexOf.call(nodes,event);//如果点击的元素不是button,那就看点击的元素是不是button的后代
  if(event.target.className=='delete'||index>-1){
    //执行函数
  }
},false);

这样就算button里面再复杂也不怕了

PHP中文网

你这理解就不对,谁给你说可能是button,可能是i标签了。你点击按钮的时候,你看是哪个标签。e.target.tagName.自己去测试一下。

伊谢尔伦

console.log(e.target) 看看 点在 i 和 button 的区别。。
貌似 e.target.nodeName 可以区分是 i 还在 button , 再结合 className 的话, 可以用委托事件 分别处理

PHPz
$('ul').on('click', '.delete', function(){

});

$('ul').on('click', '.save', function(){

});
阿神

那就不用事件代理了嘛

<button class="delete" onclick="delete_li()"><i classs="fa fa-cross"></i> 删除</button>
<button class="save" onclick="append_li()"><i classs="fa fa-plus"></i> 添加</button>

<button class="delete" onclick="delete_li()">
    <i classs="fa fa-cross"></i>
    <p><span>删除</span></p>
</button>
<button class="save" onclick="append_li()">
    <i classs="fa fa-cross"></i>
    <p><span>添加</span></p>
</button>
function delete_li(e){
  //todo
};
function append_li(e){
  //todo
};

估计楼主看了,又要说不优雅:)

大家讲道理

其它的html都不变 js代码如下

$('#ul').delegate('button', 'click', function(ev) {
            var target = ev.target;
            if ($(target).is('.delete')) {
                console.log('delete');
            } else {
                console.log('save');
            }
        })
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号