jQuery事件委托之Safari


Posted in Javascript onJuly 05, 2016

什么是事件委托

事件委托是Jquery中一种事件绑定的方式,不同于常见的事件绑定方式将事件绑定在目标元素上,而是将事件绑定在父级元素上通过事件冒泡来执行绑定函数。

//常见的事件绑定(Jquery)
$(element).click(function(){
//do something
})
//事件委托(Jquery)
$(parents).on("click",element,function(){
//do something
})

事件委托的原理

事件委托将事件监听绑定在目标元素的父级上,当目标元素响应事件时冒泡到绑定事件的父级上,进行判断该事件的目标元素是否是传入的元素,如果是就执行传入的函数。

//简单实现Jquery的事件委托
<ul id="oParent"></ul>
<a id="oClick" href="javascript:void(0)">click</a>
<script type="text/javascript">
var oParent=document.getElementById("oParent"),oClick=document.getElementById("oClick");
Object.prototype.on=function(ev,fn,obj){
var sClass=Object.prototype.toString.call(obj);
if(obj||sClass.indexOf("HTML")===-1){//假装判断一下是否需要事件委托
this.addEventListener(ev,function(e){
var e=e||window.event;
if(e.target===obj&&e.type===ev){
fn.call(e.target);//传入目标元素
}
},false);
}else{
this.addEventListener(ev,fn,false);
}
}
document.on("click",function(){console.log(this)},oClick);

没有做任何的兼容以及其他处理,只是为了了解原理,大家有什么问题可以留言指出。
事件委托有什么用呢

说这么多东西,到底事件委托有什么用呢?我认为事件委托最大的好处在于,动态生成的元素还会保留原有的事件绑定。

//a点击的时候,ul都会新增一个li,新增的li都有绑定事件
<ul id="oUl">
<li><li>
</ul>
<a id="addBtn" href="javascript:void(0)" target="_self">新增li</a>
<script>
//使用常用事件绑定实现
$("#oUl").find("li").on("click",function(){
//do something
})
$("#addBtn").on("click",function(){
$("#oUl").append("<li></li>");
$("#oUl").find("li").on("click",function(){
//do something
})
})
//先不说性能问题,这样的实现美观,符合逻辑吗
//使用事件委托实现
$("document").on("click","#oUl li",function(){//这里委托元素是灵活的,只要是父级就行,只是不是动态生成(动态生成就失去事件委托的意义了)
//do something
})
$("#addBtn").on("click",function(){
$("#oUl").append("<li></li>");
})
//这样的代码是不是简洁多了,解决了重复绑定的问题

今天的主题,事件委托之Sarfari

一次项目中遇到的问题,click事件委托在移动端的safari上失效了

<p class="loadmore">加载更多</p>
<script type="text/javascript">
$(document).on("click",".loadmore",function(){
alert("ok")
})
</script>

看上面的代码,很简单吧,没什么问题吧,除了ios的safari,其他浏览器都能正常的弹出“ok”,一开始想到会不会是什么有地方把冒泡阻止了,但是没有找到,jq的问题?,换了还是不行。正常的绑定(不使用事件委托)没问题,其他想到会不会是jq的bug,如果是jq的bug,那么以前的项目也会有类似的bug,于是到线上去找相关的代码

<a id="test" target="_slef" href="javascript:void(0)">test</a>
<script>
$("document").on("click","#test",function(){
//do something
})
</script>

在安卓和ios设备上测试,没有任何问题,代码都差不多啊,但是大家注意到没,标签不一样(html语义化多重要啊),于是将p换成a,问题完美解决,最后去谷歌了一下。

ios的safari中当使用委托给一个元素添加click事件时,如果事件是委托到 document 或 body 上,并且委托的元素是默认不可点击的(如 div, span 等),此时 click 事件会失效。

原因很清楚了,safari中不可点击元素的click事件不会冒泡到document和body上。

解决办法

1.将click事件直接绑定到元素上(不使用事件委托)

2.需要绑定click事件的元素改成<a>或者<button>等可点击元素

3.将click事件委托到非doucument或body的父级元素上

4.给目标元素添加一条css样式 cursor:pointer(推荐这种,方便省事)

以上所述是小编给大家介绍的jQuery事件委托之Safari,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jquery tools 系列 scrollable(2)
Sep 06 Javascript
jQeury淡入淡出需要注意的问题
Sep 08 Javascript
Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(二)
Dec 10 Javascript
js获取及修改网页背景色和字体色的方法
Dec 29 Javascript
限制复选框最多选择项的实现代码
May 30 Javascript
video.js使用改变ui过程
Mar 05 Javascript
jQuery插件HighCharts绘制的基本折线图效果示例【附demo源码下载】
Mar 07 Javascript
Vue 将后台传过来的带html字段的字符串转换为 HTML
Mar 29 Javascript
D3.js(v3)+react 实现带坐标与比例尺的散点图 (V3版本)
May 09 Javascript
功能完善的小程序日历组件的实现
Mar 31 Javascript
vue2.* element tabs tab-pane 动态加载组件操作
Jul 19 Javascript
在vue中import()语法不能传入变量的问题及解决
Apr 01 Vue.js
一道优雅面试题分析js中fn()和return fn()的区别
Jul 05 #Javascript
JS实现环形进度条(从0到100%)效果
Jul 05 #Javascript
JQuery组件基于Bootstrap的DropDownList(完整版)
Jul 05 #Javascript
结合代码图文讲解JavaScript中的作用域与作用域链
Jul 05 #Javascript
jQuery的Each比JS原生for循环性能慢很多的原因
Jul 05 #Javascript
Node.js实现文件上传
Jul 05 #Javascript
JavaScript数组方法大全(推荐)
Jul 05 #Javascript
You might like
PHP编程网上资源导航
2006/10/09 PHP
解决中英文字符串长度问题函数
2007/01/16 PHP
PHP随机生成信用卡卡号的方法
2015/03/23 PHP
PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)
2016/12/14 PHP
PHP使用redis位图bitMap 实现签到功能
2019/10/08 PHP
js弹出div并显示遮罩层
2014/02/12 Javascript
元素未显示设置width/height时IE中使用currentStyle获取为auto
2014/05/04 Javascript
使用原生JS实现弹出层特效
2014/12/22 Javascript
基于replaceChild制作简单的吞噬特效
2015/09/21 Javascript
JavaScript判断是否是微信浏览器
2016/06/13 Javascript
javascript作用域、作用域链(菜鸟必看)
2016/06/16 Javascript
纯js实现的积木(div层)拖动功能示例
2017/07/19 Javascript
在Vue中使用echarts的方法
2018/02/05 Javascript
Vue.js 中取得后台原生HTML字符串 原样显示问题的解决方法
2018/06/10 Javascript
JS原型对象操作实例分析
2020/06/06 Javascript
在vue中通过render函数给子组件设置ref操作
2020/11/17 Vue.js
[08:08]2014DOTA2国际邀请赛中国区预选赛精彩TOPPLAY
2014/06/25 DOTA
[01:17]炒鸡美酒第四天TA暴走
2018/06/05 DOTA
[46:44]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD BO3 第二场 3月7日
2021/03/11 DOTA
Python编程中的反模式实例分析
2014/12/08 Python
Python的动态重新封装的教程
2015/04/11 Python
Python最基本的输入输出详解
2015/04/25 Python
Python利用pandas计算多个CSV文件数据值的实例
2018/04/19 Python
Python3利用Dlib19.7实现摄像头人脸识别的方法
2018/05/11 Python
Python判断字符串是否为字母或者数字(浮点数)的多种方法
2018/08/03 Python
在Python 中实现图片加框和加字的方法
2019/01/26 Python
Python插入Elasticsearch操作方法解析
2020/01/19 Python
解决pyinstaller 打包exe文件太大,用pipenv 缩小exe的问题
2020/07/13 Python
一套软件测试笔试题
2014/07/25 面试题
不听老师话的万能检讨书
2014/10/04 职场文书
2014年依法行政工作总结
2014/11/19 职场文书
事业单位工作人员年度考核个人总结
2015/02/12 职场文书
简历自我评价模板
2015/03/11 职场文书
毕业酒会致辞
2015/07/29 职场文书
工人先锋号事迹材料(2016精选版)
2016/03/01 职场文书
Redis延迟队列和分布式延迟队列的简答实现
2021/05/13 Redis