关于IOS浏览器:document,body的click事件触发规则

今天做了个手机页面,点击某个按钮->弹出菜单,再点击菜单以外的任意位置->关闭菜单,在其他浏览器里面没有问题,但是在IOS浏览器中并不会关闭。

网上解决这个bug的帖子很多,这篇帖子主要是讲原理,这里写个简单的代码,大家可以复制到自己页面中去实验:

<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"/>
</head>
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<style>
*{min-height:100px; line-height:100px;}
body{ background:#ddd;}
a,input{display:block;}
div{background:#9CF;}
</style>
<body>
    <a href="#" >链接</a>
    <input type="button" value="按钮"/>
    <div>div或span等</div>
</body>
</html>
<script>

$("body").bind("click",function(){
    alert("body 被点击")
})
</script>

上面这段代码在其他浏览器里面没有问题,在IOS的浏览器中,点击链接和按钮都会有弹窗,但是点击其他区域却没有。

原因是因为IOS浏览器的window、document、body并不接受click事件,按钮和链接才接受click事件

我们做一个比喻来理解这个事件是怎么运作的:

屏幕被点击后,系统会发送一个事件公告(click),链接和按钮收到这个公告后会处理相应的行为(比如打开个新页面,提交表单,用户绑定的其他行为)window、document、body并不会搭理这个公告,跟没看到似的,自然也就没有弹窗出现body只接受内部的冒泡事件,点击按钮后触发了按钮的click事件,然后按钮会告诉自己的上级(body):老大,我被点击了,body会说:好的,我会处理的,这时候弹窗就出来了。body里面的div,span等标签默认是不会理睬click事件公告的,但是我们可以开启他,开启后他们就跟按钮一样,可以接受click事件,并汇报给上级。开启方法:给标签绑定一个任意事件↓

1.HTML标签中添加事件属性

<div onMouseOver>div或span等</div>
<div onClick>div或span等</div>
<div onKeyDown>div或span等</div>

2.用js或者jquery绑定一个事件

$("body div").bind("click",function(){})

所以最后我们的弹出菜单可以这样写

/*给body里面的任意元素绑定事件,让这些标签能接受click事件*/$("body>*").bind("click",function(){});

$("#button").bind("click",function(e){/*给按钮绑定点击事件*/    $("#menu").show();//按钮点击后显示菜单        $("body").one("click",function(){/*菜单显示后:给body绑定点击事件,执行一次后自动删除这个绑定*/        $("#menu").hide();//body收到click事件后关闭菜单    });    e.stopPropagation();//停止冒泡,按钮被点击后不告诉body,因为click事件如果冒泡到body会关闭菜单。

})
$("#menu").bind("click",function(e){/*给菜单绑定点击事件*/   e.stopPropagation();//停止冒泡,菜单被点击后不告诉body,不然菜单要被关闭})
 
时间: 2024-08-11 07:40:28

关于IOS浏览器:document,body的click事件触发规则的相关文章

[ 面试没回答上的问题2]IOS上给body绑定click事件的bug

面试被问到ios上的bug,自己提到绑定click事件的bug,但是并没有把问题讲的很清楚,这里再清理一下思路. 这个bug只在IOS上有,包括ihone,ipad,由于ios浏览器都用的safari内核,所以ios浏览器全部中枪. bug描述 在进行事件委托时,如果将未存在于DOM的元素事件直接委托到body上的话,会导致事件委托失效,调试结果为事件响应到body子元素为止,既没有冒泡到body上,也没有被body所捕获.但如果事件是DOM元素本身具有的,则不会触发bug.换而言之,只有元素的

Fastclick 导致click事件触发两次的问题

我在移动web上使用Fastclick这个库去解决300ms延迟问题,但是在安卓4.2下的webview中引发了另一个比较奇怪的bug. 在A页面中有个 a button,在B页面中有个 b button,a和b都在同一个position,给a和b都注册一个click事件.a的click事件触发后跳转到B页面.当a被点击后调到B页面,你会发现b按钮的click事件也被触发了. 没错,事件'穿透'了两个页面! 但其实并没有穿透,点击a按钮时,其实有如下两个动作: fastclick用touchst

Fastclick 导致click事件触发两次的问题,fastclickclick

文章原文csdn链接:www.foreverpx.cn 我在移动web上使用Fastclick这个库去解决300ms延迟问题,但是在安卓4.2下的webview中引发了另一个比较奇怪的bug. 在A页面中有个 a button,在B页面中有个 b button,a和b都在同一个position,给a和b都注册一个click事件.a的click事件触发后跳转到B页面.当a被点击后调到B页面,你会发现b按钮的click事件也被触发了. 没错,事件‘穿透’了两个页面! 但其实并没有穿透,点击a按钮时,

[ios]IOS的AppDelegate方法中的事件触发调用 以及 关闭 ios应用程序

IOS的AppDelegate方法中的事件触发调用 参考:http://blog.sina.com.cn/s/blog_a573f7990101bphp.html //当应用程序将要进入非活动状态执行,在此期间,应用程序不接受消息或事件,比如来电 - (void)applicationWillResignActive:(UIApplication *)application { NSLog(@"应用程序将要进入非活动状态,即将进入后台"); } //应用程序已经进入后台运行 - (vo

手机浏览器下IScroll中click事件

产品的h5页面几乎都使用了iscroll插件,如果a标签在iscroll里,在部分手机浏览器中会出现无法点击的情况,不管是绑定click事件还是使用a标签的href属性.href属性偶尔还会能点击,click事件完全不能. 如果用button或input代替a,都能响应click事件. 如果用微信内置浏览器,都能响应click事件(nubia除外).QQ浏览器也能响应. 也就是出现此问题跟手机本地浏览器,iscroll,a标签都有关系. iScroll uses various techniqu

checkbox:click事件触发文本框显示隐藏

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>checkbox</title> <script src="jquery.js"></script> </head> <body> <form action="#"

IOS的AppDelegate方法中的事件触发调用

用到的时候老是要去找,还是记下来好= = IOS中AppDelegate中的生命周期事件的调用条件: [cpp] view plaincopy //当应用程序将要进入非活动状态执行,在此期间,应用程序不接受消息或事件,比如来电 - (void)applicationWillResignActive:(UIApplication *)application { NSLog(@"应用程序将要进入非活动状态,即将进入后台"); } //应用程序已经进入后台运行 - (void)applica

checkbox:click事件触发span元素内容改变

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>checkbox</title> <script src="jquery.js"></script> </head> <body> <p>我想去<span id="

移动端click事件延迟300ms的原因以及解决办法

这要追溯至 2007 年初.苹果公司在发布首款 iPhone 前夕,遇到一个问题 —— 当时的网站都是为大屏幕设备所设计的.于是苹果的工程师们做了一些约定,应对 iPhone 这种小屏幕浏览桌面端站点的问题.这当中最出名的,当属双击缩放(double tap to zoom).这也是会有上述 300 毫秒延迟的主要原因. 当用户一次点击屏幕之后,浏览器并不能立刻判断用户是要进行双击缩放,还是想要进行单击操作.因此,iOS Safari 就等待 300 毫秒,以判断用户是否再次点击了屏幕. 于是,