在旧项目中,我们一般绑定事件都是用 $('selector').on('event', fn)
|| document.querySelector('selector').addEventListener('event', fn)
;
如果平时代码规范,这样写完全ojbk 点击.p
之后输出 test1
1 | <div id="id"> |
但是平时如果项目不规范,代码又写的比较乱….emmmm,很有可能出现一些逻辑上的低级错误,比如这种,在某个函数调了两次,所以这里就绑定了两次…点击之后会输出两次的 test
1 | <div id="id"> |
这种情况平时工作不注意真的有可能发生,而且排查也只能说平时在看接口或改代码的时候 发现随手改
一般为了避免这种失误重复调用的操作,有几种方法:
把事件处理函数抽出来,这样就算重复绑定,浏览器检测到是同个函数引用,会做相应的优化,所以不会重复绑定到事件上
1
2
3
4
5
6
7
8<script>
function add(selector, fn) { document.querySelector(selector).addEventListener('click',fn); }
const evFn= e=> console.log(e.currentTarget.innerHTML);
function fn1() { add('.p', evFn)};
fn1();
fn1();
fn1();
</script>使用 event.stopImmediatePropagation
官方给出的说明是:
如果某个元素有多个相同类型事件的事件监听函数,则当该类型的事件触发时,多个事件监听函数将按照顺序依次执行.如果某个监听函数执行了 event.stopImmediatePropagation()方法,则除了该事件的冒泡行为被阻止之外(event.stopPropagation方法的作用),该元素绑定的后序相同类型事件的监听函数的执行也将被阻止.
简单来说就是,执行了event.stopImmediatePropagation()
之后,后续的绑定在该dom上的相同类型事件都不再被响应,也不冒泡。
demo3
代码,点击 test1 之后,只会在控制台输出一行 test1
,其他 该元素的点击事件,#id点击事件都不会被响应
1 | <div id="id"> |
在实际项目中,还是比较建议把事件处理逻辑抽出来当一个函数,毕竟在多人项目里面 stopImmediatePropagation
比较容易误伤队友…