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入门教程(8) Location地址对象
Jan 31 Javascript
jquery 将disabled的元素置为enabled的三种方法
Jul 25 Javascript
Lazy Load 延迟加载图片的jQuery插件中文使用文档
Oct 18 Javascript
js获取location.href的参数实例代码
Aug 02 Javascript
connect中间件session、cookie的使用方法分享
Jun 17 Javascript
EXT中单击button按钮grid添加一行(光标位置可设置)的实例代码
Jun 02 Javascript
AngularJS基础 ng-keypress 指令简单示例
Aug 02 Javascript
JavaScript设计模式之单例模式详解
Jun 09 Javascript
基于axios 解决跨域cookie丢失的问题
Sep 26 Javascript
详解Vue内部怎样处理props选项的多种写法
Nov 06 Javascript
JavaScript文本特效实例小结【3个示例】
Dec 22 Javascript
Vue最新防抖方案(必看篇)
Oct 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
极典R601SW收音机
2021/03/02 无线电
[原创]效率较高的php下读取文本文件的代码
2008/07/02 PHP
ThinkPHP之用户注册登录留言完整实例
2014/07/22 PHP
PHP使用Face++接口开发微信公众平台人脸识别系统的方法
2015/04/17 PHP
Yii2实现增删改查后留在当前页的方法详解
2017/01/13 PHP
PHP扩展Swoole实现实时异步任务队列示例
2019/04/13 PHP
会自动逐行上升的文本框
2006/06/30 Javascript
高亮显示web页表格行的javascript代码
2010/11/19 Javascript
juqery 学习之五 文档处理 包裹、替换、删除、复制
2011/02/11 Javascript
JS 无限级 Select效果实现代码(json格式)
2011/08/30 Javascript
Js 冒泡事件阻止实现代码
2013/01/27 Javascript
jquery实现在光标位置插入内容的方法
2015/02/05 Javascript
AngularJS的表单使用详解
2015/06/17 Javascript
JavaScript实现将文本框的值插入指定位置的方法
2015/08/13 Javascript
用v-html解决Vue.js渲染中html标签不被解析的问题
2016/12/14 Javascript
Vue.js中用webpack合并打包多个组件并实现按需加载
2017/02/17 Javascript
angularjs的select使用及默认选中设置
2017/04/08 Javascript
老生常谈Bootstrap媒体对象
2017/07/06 Javascript
浅析node应用的timing-attack安全漏洞
2018/02/28 Javascript
layer弹出层自定义提交取消按钮的例子
2019/09/10 Javascript
[00:33]2016完美“圣”典风云人物:Sccc宣传片
2016/12/03 DOTA
Python中的pprint折腾记
2015/01/21 Python
Python机器学习之scikit-learn库中KNN算法的封装与使用方法
2018/12/14 Python
Python 操作 ElasticSearch的完整代码
2019/08/04 Python
Python高并发和多线程有什么关系
2020/11/14 Python
详解修改Anaconda中的Jupyter Notebook默认工作路径的三种方式
2021/01/24 Python
css3的transform中scale缩放详解
2014/12/08 HTML / CSS
简述Linux文件系统通过i节点把文件的逻辑结构和物理结构转换的工作过程
2012/04/17 面试题
拉丁舞学习者的自我评价
2013/10/27 职场文书
老师推荐信
2013/10/28 职场文书
市场营销专业推荐信
2013/11/03 职场文书
分公司经理岗位职责
2013/11/11 职场文书
个人政治思想总结
2015/03/05 职场文书
银行求职信模板
2015/03/20 职场文书
《水浒传》读后感3篇(范文)
2019/09/19 职场文书
python3 字符串str和bytes相互转换
2022/03/23 Python