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 表格插件整理
Apr 27 Javascript
javascript客户端解决方案 缓存提供程序
Jul 14 Javascript
简单实用的反馈表单无刷新提交带验证
Nov 15 Javascript
jQuery实现的导航条切换可显示隐藏
Oct 22 Javascript
JavaScript数组前面插入元素的方法
Apr 06 Javascript
使用coffeescript编写node.js项目的方法汇总
Aug 05 Javascript
JS如何判断是否为ie浏览器的方法(包括IE10、IE11在内)
Dec 13 Javascript
浅谈发布订阅模式与观察者模式
Apr 09 Javascript
vue指令v-html使用过滤器filters功能实例
Oct 25 Javascript
js实现随机点名程序
Sep 17 Javascript
JS数组Reduce方法功能与用法实例详解
Apr 29 Javascript
JavaScript实现像雪花一样的Hexaflake分形
Jul 07 Javascript
一道优雅面试题分析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
Laravel最佳分割路由文件(routes.php)的方式
2016/08/04 PHP
PHP实现的方程求解示例分析
2016/11/11 PHP
使用PHPMailer发送邮件实例
2017/02/15 PHP
laravel异步监控定时调度器实例详解
2019/06/21 PHP
script标签的 charset 属性使用说明
2010/12/04 Javascript
关于onScroll事件在IE6下每次滚动触发三次bug说明
2011/09/21 Javascript
javascript高级程序设计第二版第十二章事件要点总结(常用的跨浏览器检测方法)
2012/08/22 Javascript
JS实现字体选色板实例代码
2013/11/20 Javascript
jQuery获取当前对象标签名称的方法
2014/02/07 Javascript
原生js实现数字字母混合验证码的简单实例
2015/12/10 Javascript
JavaScript面向对象分层思维全面解析
2016/11/22 Javascript
jQuery实现立体式数字动态增加(animate方法)
2016/12/21 Javascript
jQuery编写设置和获取颜色的插件
2017/01/09 Javascript
JS中mouseup事件丢失的原因与解决办法
2017/06/14 Javascript
JS+HTML5 FileReader实现文件上传前本地预览功能
2020/03/27 Javascript
微信小程序中button组件的边框设置的实例详解
2017/09/27 Javascript
vue页面加载闪烁问题的解决方法
2018/03/28 Javascript
WebPack配置vue多页面的技巧
2018/05/15 Javascript
jQuery中each遍历的三种方法实例分析
2018/09/07 jQuery
利用原生JS实现data方法示例代码
2019/05/28 Javascript
对layui数据表格动态cols(字段)动态变化详解
2019/10/25 Javascript
javascript实现简易数码时钟
2020/03/30 Javascript
matplotlib简介,安装和简单实例代码
2017/12/26 Python
Python检测网络延迟的代码
2018/05/15 Python
Python的高阶函数用法实例分析
2019/04/11 Python
Python二维数组实现求出3*3矩阵对角线元素的和示例
2019/11/29 Python
pytorch 多分类问题,计算百分比操作
2020/07/09 Python
python实现图像高斯金字塔的示例代码
2020/12/11 Python
马来西亚领先的在线礼品店:Giftr
2018/08/23 全球购物
C/C++程序员常见面试题二
2015/11/19 面试题
应用化学专业本科生求职信
2013/09/29 职场文书
机械制造毕业生求职信
2014/03/03 职场文书
大学生万能检讨书范例
2014/10/04 职场文书
2014年社区计生工作总结
2014/11/18 职场文书
Python超简单容易上手的画图工具库推荐
2021/05/10 Python
Redis 常见使用场景
2021/08/30 Redis