Skip to content

Instantly share code, notes, and snippets.

@ufologist
Created September 19, 2017 09:06
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ufologist/b31e0ec1af14d4ea24bde3c28731901e to your computer and use it in GitHub Desktop.
Save ufologist/b31e0ec1af14d4ea24bde3c28731901e to your computer and use it in GitHub Desktop.
iOS body click 事件冒泡的 bug
<!DOCTYPE html>
<html lang="en">
<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">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>iOS body click 事件冒泡的 bug</title>
</head>
<body>
<h1>点击 h1 不会冒泡到 body</h1>
<p>点击 p 不会冒泡到 body</p>
<div>点击 div 不会冒泡到 body</div>
<br>
<span>点击 span 不会冒泡到 body</span>
<br>
<br>
<a href="#">点击 a 之类本身就具备交互功能的元素才能冒泡到 body</a>
<input type="text">
<select name="" id=""></select>
<script src="//cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script>
// 影响1: 给 body 注册 click 事件, 会没有效果
document.body.addEventListener('click', function() {
alert('body');
}, false);
// 影响2: 通过 body 代理 click 事件(实质上也是给 body 注册 click 事件)
$(document.body).on('click', 'h1, p, div, span', function(event) {
alert(event.target.tagName);
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<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">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>iOS body click 事件冒泡的 bug(修复方法)</title>
</head>
<body style="cursor: pointer;">
<h2>神奇的 <code>cursor: pointer;</code></h2>
<p>可以直接在 body 上面添加或者在每个不具备交互功能的元素上添加</p>
<h1>点击 h1 冒泡到 body</h1>
<p>点击 p 冒泡到 body</p>
<div>点击 div 冒泡到 body</div>
<br>
<span>点击 span 冒泡到 body</span>
<script src="//cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script>
document.body.addEventListener('click', function() {
alert('body');
}, false);
$(document.body).on('click', 'h1, p, div, span', function(event) {
alert(event.target.tagName);
});
</script>
</body>
</html>
@ufologist
Copy link
Author

ufologist commented Sep 19, 2017

踩坑记

随便写了个简单的页面, 在 iOS 上查看发现给 body 监听的 click 事件怎么没有反应?

感觉好坑啊, 谁会想到这么简单的事情也有坑等着呢?

最简单的解决办法也是神奇, 给 body 搞个样式 cursor:pointer 就可以了, 你说神奇不神奇.

更牛的是, jQuery 的文档中早就提过这个问题了, jQuery 踩的坑果然多啊.

最后感慨 2010 年就存在的老 bug, 没想现在到了 iOS 10.3.3, 还是没有解决. ╮(╯_╰)╭

影响

  • 给 body 注册 click 事件, 会没有效果
  • 通过 body 代理 click 事件(实质上也是给 body 注册 click 事件), 会没有效果

参考

  • iOS下click事件不冒泡的解决

  • .live() | jQuery API Documentation

    On mobile iOS (iPhone, iPad and iPod Touch) the click event does not bubble to the document body for most elements and cannot be used with .live() without applying one of the following workarounds:

    • Use natively clickable elements such as a or button, as both of these do bubble to document.
    • Use .on() or .delegate() attached to an element below the level of document.body, since mobile iOS does bubble within the body.
    • Apply the CSS style cursor:pointer to the element that needs to bubble clicks (or a parent including document.documentElement).
  • Click event delegation on the iPhone

@dyun8080
Copy link

dyun8080 commented Mar 6, 2019

学习了~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment