关于jquery绑定事件、解绑、事件冒泡的探索
在最近的项目中,我发现了jquery一个神奇的现象,有关于绑定事件以及事件解除绑定,让我对jquery获取指定的DOM元素有了更新的理解,下面我想描述一下这个有趣的经历。
有一个需求是这样的:
页面上有一个投票按钮,点击“给TA投票”按钮会调用ajax给后台传数据,后台处理好数据后,如果成功的话会弹一个投票成功的弹窗,用来提示用户,“给TA投票”按钮会变为“已投票”,同时这个按钮将不能再次被点击。于是这里就有了给DOM元素绑定事件以及事件解除绑定的问题。
其实解决这个问题很简单:
最简单的办法:使用off()
html: <div class="voteBtn">给TA投票</div> js: $('.voteBtn').on('click',function () { var $this = $(this); $.ajax({ url:url, data:data, type:'POST', dataType:'json', success:function( data){ if( data.status == 'success'){ alert('投票成功'); $this.off('click').text('今日已投票'); }else if( data.status == 'error'){ alert(data.data.msg); } } }); })
BUT 我想能不能不用off()呢?于是我又想了另外一个办法:
如果我再给 voteBtn 一个class————“voteActive”,然后我使用选择器选择voteActive这个DOM元素,给它绑定click事件,在click事件内部再把这个voteActive类删掉,这样,选择器选择不到voteActive这个DOM元素,我给一个选择不到的元素绑定事件不就相当于没绑吗!我自认为很机智,实际上事实并非如此。
以下是我愚蠢的代码:
$('.voteBtn.voteActive').on('click',function () { var $this = $(this); $.ajax({ url:url, data:data, type:'POST', dataType:'json', success:function( data){ if( data.status == 'success'){ alert('投票成功'); $this.removeClass('voteActive').text('今日已投票'); }else if( data.status == 'error'){ alert(data.data.msg); } } }); })
事实上,这么写第二次点击投票按钮还是会执行点击事件,为什么呢?
这是因为:
第二次点击按钮时,虽然$('.voteBtn.voteActive')不能成功获取到投票按钮这个DOM元素了,但是,我把$('.voteBtn.voteActive')在控制器输出了一下,得到了这样的结果:
虽然length是等于0了,证明没有获取到$('.voteBtn.voteActive')这个元素,但是它的context却是document,这说明我的第二次点击其实是把事件绑定到了document上,所以我再次点击投票按钮时,其实相当于点击的是document。原来事件冒泡到了父级元素上!!!
这时,我想到了用on绑定事件的另一种用法:
$('document').on('click','.voteActive',function () { var $this = $(this); //其他代码... $this.removeClass('voteActive'); //其他代码... });
这个用法的意思是:
给document绑定一个click事件,如果冒泡冒到voteActive上时,执行这个事件,否则不执行。这样我的第二个方法就能正常使用了。
这次探索更新了我对事件绑定的一些理解,并不是获取不到指定的元素绑定的事件就一定不奏效,别忘了还有事件冒泡呀!思想不要太简单!
好了,为了验证自己的一个脑洞,进行了这样一次尝试,也算有些收获。希望继续努力吧~
相关推荐
<table id="table" class="table table-striped table-bordered table-hover table-nowrap" width="100%&qu