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 相关文章推荐
javascript面向对象之Javascript 继承
May 04 Javascript
浅谈Javascript事件处理程序的几种方式
Jun 27 Javascript
解决用jquery load加载页面到div时,不执行页面js的问题
Feb 22 Javascript
基于jquery实现的自动补全功能
Mar 12 Javascript
jQuery选择器用法实例详解
Dec 17 Javascript
jQuery.datatables.js插件用法及api实例详解
Oct 28 Javascript
node.js基于express使用websocket的方法
Nov 09 Javascript
React BootStrap用户体验框架快速上手
Mar 06 Javascript
JS代码实现电脑配置检测功能
Mar 21 Javascript
vue cli 3.0 搭建项目的图文教程
May 17 Javascript
深入分析jQuery.one() 函数
Jun 03 jQuery
js实现鼠标拖曳效果
Dec 30 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
第十五节--Zend引擎的发展
2006/11/16 PHP
php加速缓存器opcache,apc,xcache,eAccelerator原理与配置方法实例分析
2020/03/02 PHP
Thinkphp框架使用list_to_tree 实现无限级分类列出所有节点示例
2020/04/04 PHP
javascript下判断一个对象是否具有指定名称的属性的的代码
2010/01/11 Javascript
基于jQuery的星级评分插件
2011/08/12 Javascript
jquery 操作两个select实现值之间的互相传递
2014/03/07 Javascript
jQuery实现限制textarea文本框输入字符数量的方法
2015/05/28 Javascript
轻松学习jQuery插件EasyUI EasyUI创建RSS Feed阅读器
2015/11/30 Javascript
json格式数据的添加,删除及排序方法
2016/01/21 Javascript
jQuery webuploader分片上传大文件
2016/11/07 Javascript
详解Vue.js——60分钟组件快速入门(上篇)
2016/12/05 Javascript
jQuery与js实现颜色渐变的方法
2016/12/30 Javascript
javascript作用域链与执行环境详解
2017/03/25 Javascript
Vue2.0 UI框架ElementUI使用方法详解
2017/04/14 Javascript
浅谈JS 数字和字符串之间相互转化的纠纷
2017/10/20 Javascript
浅谈JS和jQuery的区别
2019/03/27 jQuery
mpvue实现左侧导航与右侧内容的联动
2019/10/21 Javascript
vue-video-player 解决微信自动全屏播放问题(横竖屏导致样式错乱问题)
2020/02/25 Javascript
JS浏览器BOM常见操作实例详解
2020/04/27 Javascript
vue+elementui实现点击table中的单元格触发事件--弹框
2020/07/18 Javascript
Vue中的nextTick作用和几个简单的使用场景
2021/01/25 Vue.js
[43:24]VG vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
基于Python 的进程管理工具supervisor使用指南
2016/09/18 Python
python中类变量与成员变量的使用注意点总结
2017/04/29 Python
pandas中去除指定字符的实例
2018/05/18 Python
浅谈对pytroch中torch.autograd.backward的思考
2019/12/27 Python
django 文件上传功能的相关实例代码(简单易懂)
2020/01/22 Python
迪卡侬英国官网:Decathlon英国
2017/04/08 全球购物
Orlebar Brown官网:设计师泳裤和泳装
2020/12/08 全球购物
什么是java序列化,如何实现java序列化
2012/11/14 面试题
公司外出活动方案
2014/08/14 职场文书
交通工程专业推荐信
2014/09/06 职场文书
党员反对四风思想汇报范文
2014/10/25 职场文书
毕业生入职感言
2015/07/31 职场文书
Python多线程实用方法以及共享变量资源竞争问题
2022/04/12 Python
Java Spring Boot请求方式与请求映射过程分析
2022/06/25 Java/Android