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 EasyUI API 中文文档 - MenuButton菜单按钮使用介绍
Oct 06 Javascript
JS实现一键回顶功能示例代码
Oct 28 Javascript
Node.js的特点和应用场景介绍
Nov 04 Javascript
jQuery在线选座位插件seat-charts特效代码分享
Aug 27 Javascript
ros::spin() 和 ros::spinOnce()函数的区别及详解
Oct 01 Javascript
JS实现禁止高频率连续点击的方法【基于ES6语法】
Apr 25 Javascript
jQuery 表单序列化实例代码
Jun 11 jQuery
详解如何实现一个简单的Node.js脚手架
Dec 04 Javascript
Vue+Jwt+SpringBoot+Ldap完成登录认证的示例代码
May 21 Javascript
Vue表单及表单绑定方法
Sep 04 Javascript
详解Nuxt内导航栏的两种实现方式
Apr 16 Javascript
JS原生实现轮播图的几种方法
Mar 23 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
PHP获取文件绝对路径的代码(上一级目录)
2011/05/29 PHP
百度ping方法使用示例 自动ping百度
2014/01/26 PHP
阿里云PHP SMS短信服务验证码发送方法
2017/07/11 PHP
CentOS7系统搭建LAMP及更新PHP版本操作详解
2020/03/26 PHP
PHP date_default_timezone_set()设置时区操作实例分析
2020/05/16 PHP
javascript获取当前日期时间及其它操作函数
2011/01/11 Javascript
jquery插件lazyload.js延迟加载图片的使用方法
2014/02/19 Javascript
JsRender for index循环索引用法详解
2014/10/31 Javascript
javascript字符串与数组转换汇总
2015/05/26 Javascript
最新最热最实用的15个jQuery插件汇总
2015/07/05 Javascript
扩展jquery easyui tree的搜索树节点方法(推荐)
2016/10/28 Javascript
Easyui笔记2:实现datagrid多行删除的示例代码
2017/01/14 Javascript
JavaScript定时器制作弹窗小广告
2017/02/05 Javascript
使用vue.js编写蓝色拼图小游戏
2017/03/17 Javascript
原生JS实现导航下拉菜单效果
2020/11/25 Javascript
通过js动态创建标签,并设置属性方法
2018/02/24 Javascript
vue-devtools的安装步骤
2018/04/23 Javascript
javacript replace 正则取字符串中的值并替换【推荐】
2018/09/13 Javascript
jQuery实现的简单日历组件定义与用法示例
2018/12/24 jQuery
vue解决花括号数据绑定不成功的问题
2019/10/30 Javascript
动态创建类实例代码
2009/10/07 Python
django 删除数据库表后重新同步的方法
2018/05/27 Python
python中matplotlib条件背景颜色的实现
2019/09/02 Python
python实现统计代码行数的小工具
2019/09/19 Python
Python从入门到精通之环境搭建教程图解
2019/09/26 Python
Pandas —— resample()重采样和asfreq()频度转换方式
2020/02/26 Python
python的pip有什么用
2020/06/17 Python
如何实现一个python函数装饰器(Decorator)
2020/10/12 Python
python爬虫爬取某网站视频的示例代码
2021/02/20 Python
Shoes For Crews法国官网:美国领先的防滑鞋设计和制造商
2018/01/01 全球购物
美国著名的家居用品购物网站:Bed Bath & Beyond
2018/01/05 全球购物
2015年健康教育工作总结
2015/04/10 职场文书
消防安全月活动总结
2015/05/08 职场文书
2015年学校办公室工作总结
2015/05/26 职场文书
Elasticsearch 批量操作
2022/04/19 Python
Python 文字识别
2022/05/11 Python