移动端onTouchMove事件 以及Fixed定位的坑

就为了一个小特效搞了一天时间!话很少说html

需求是这样的:在页面上作一个浮动的小图标,能够拖拽移动它。浏览器

效果是这样的:函数

代码是这样的:性能


你们都知道,移动端拖拽事件主要就是利用touchmove。为了防止拖拽它的时候,禁止浏览器的上下滚动,个人方法是在onTouchStart中将html和body的样式设为 height: 100%; overflow: hidden,而后在onTouchEnd中将样式清空。最后在onTouchStart,onTouchMove中添加了e.preventDefault()方法来阻止浏览器默认行为。测试

可是!PC端调试的时候好好的,而后到手机访问的时候就失效!浏览器也跟着一块儿滚犊子!体验贼差!最神奇的是,一样都是苹果自带的Safari浏览器,个人手机不行,测试的手机就正常!优化

研究了很久都没解决,而后发现PC端虽然正常,可是报了个警告:spa


什么玩意?翻译一波翻译



百度后发现:Chorme某个版本更新后,为了让页面滑动流畅的飞起来,在window、document 和 body 上注册的 touchstart 和 touchmove 事件处理函数,默认 passive为 true。浏览器会忽略默认事件的preventDefault(), 你要是强行阻止会弹出一个警告, 也就是上面那个黄黄的!调试

这时候又纳闷了,这个passive又是啥?code

Passive Event Listeners是Chrome提出的一个新的浏览器特性:Web开发者经过一个新的属性passive来告诉浏览器,当前页面内注册的事件监听器内部是否会调用preventDefault函数来阻止事件的默认行为,以便浏览器根据这个信息更好地作出决策来优化页面性能。当属性passive的值为true的时候,表明该监听器内部不会调用preventDefault函数来阻止默认滑动行为,Chrome浏览器称这类型的监听器为被动(passive)监听器。目前Chrome主要利用该特性来优化页面的滑动性能,因此Passive Event Listeners特性当前仅支持mousewheel/touch相关事件。

这时我感受找到了眉目,而后就换了一种方式!不在DOM上直接绑定方法了,而是在componentDidMount钩子里添加监听!


而后发现,成了~~啊哈哈哈

最后要提一嘴,对于那个警告网上不少帖子都说加上全局样式*{touch-action: none}就行了。我在这里告诫你们,可千万不能乱加,加了这个有些浏览器全部页面都不能滚动了!并且也只是为了清除那个警告,并无达到想要的效果。有兴趣的能够去了解一下touch-action属性。


。。。   。。。


糟糕的一天还没结束,我又发现了个新问题……就是这个浮动的小图标是fixed定位的,可是怎么不随着浏览器滚动而固定在屏幕上呢??

最后发现body的跟标签,也就是id为root的div上有transform属性!(这项目不是我写的)

规范中规定:若是元素的transform值不为none,则该元素会生成 包含块和层叠上下文

什么是包含块?包含块(Containing Block)是视觉格式化模型的一个重要概念,它与框模型相似,也能够理解为一个矩形,而这个矩形的做用是为它里面包含的元素提供一个参考,元素的尺寸和位置的计算每每是由该元素所在的包含块决定的。

说重点!包含块从新定位了坐标参考系!!因此transform会影响子元素的绝对定位(fixed定位也是绝对定位的一种)!

知道咋回事了,那就来看看前辈为何加这个transform?代码是left: 50%; transform: translate(-50%);

就是为了大屏幕下的居中定位。。而大屏幕会重定向到PC端官网,因此删掉!!

搞定!下班!

相关文章
相关标签/搜索