最新更新时间:2019年10月15日09:51:32
《猛戳-查看我的博客地图-总有你意想不到的惊喜》
本文内容:一般情况下,在应用的首页,会有一个贴边的、悬浮的、可拖动的按钮,用来快速进入具体的某个页面,或者用来调起客服,或者其他信息。
概述
本文使用 react 框架,采用组件化方案实现这个交互效果,并且完全兼容 Android 和 iOS 双端。尤其是针对 iOS 端,当页面滚动到上下边界时出现的橡皮筋效果,也做了很好的处理。方案简单易懂,希望大家参考和学习。
父组件
import React from 'react'
import Child from './Child'
export default class Parent extends React{
constructor(props){}
componentDidMount() {}
render(){
return <div id='parent' className={styles.container}>
<Child/>
</div>
}
子组件
此处的
小助手
是可拖动的的这个子组件
import React from 'react'
export default class Child extends React.PureComponent{
constructor(props){
super(props);
this.state = {}
this.relativeY = 0;//手指触摸 小助手 的点距离该元素顶部的距离
this.reachTop = false;//移动 小助手 是否超过屏幕顶部
this.reachBottom = false;//移动 小助手 是否超过屏幕底部
this.childtDom = null;
this.html = null;
}
componentDidMount() {
let _this = this;
this.childtDom = document.getElementById('child');
this.html = document.documentElement;
//页面初始化 禁止body滚动-iOS页面上下滚动的橡皮筋效果
//如果使用 touchstart childtDom上的onClick事件失效
document.body.addEventListener('touchmove', _this.preventScroll, {passive: false});
//开始触摸parent 解除body滚动
document.getElementById('parent').addEventListener('touchstart', function (e) {
//触摸的元素不是小助手 解除禁止body滚动
//触摸的元素是小助手 body处于禁止滚动状态
if(e.target.id != 'child'){
document.body.removeEventListener('touchmove', _this.preventScroll);
}
}, {passive: false});
//触摸parent结束 禁止body滚动-iOS页面上下滚动的橡皮筋效果
document.getElementById('parent').addEventListener('touchend', function () {
document.body.addEventListener('touchmove', _this.preventScroll, {passive: false});
}, {passive: false});
}
componentWillUnmount() {
//组件卸载-卸载事件
document.body.removeEventListener('touchmove', this.preventScroll);
}
/**
* 手指放在 小助手 上移动
* @param event
* @return
*/
onTouchMove(e){
let clientY = e.touches[0].clientY;//手指触摸屏幕的点距离文档顶部的距离 文档总高度可能会超过屏幕高度
let smallAssistantTop = clientY + this.relativeY;//小助手 相对屏幕顶部绝对定位的距离
this.childtDom.style.top = smallAssistantTop + 'px'
if(smallAssistantTop < 0){
this.reachTop = true;
}
if(smallAssistantTop > this.html.offsetHeight - 70){
this.reachBottom = true;
}
}
/**
* 手指放在 小助手
* @param event
* @return
*/
onTouchStart(e){
this.relativeY = e.target.offsetTop - e.touches[0].clientY
}
/**
* 手指离开 小助手
* @param event
* @return
*/
onTouchEnd(){
if(this.reachTop){
this.childtDom.style.top = 0 + 'px'
this.reachTop = false;
}
if(this.reachBottom){
this.childtDom.style.top = this.html.offsetHeight - 70 + 'px'
this.reachBottom = false;
}
}
/**
* 阻止页面滚动
* @param
* @return
*/
preventScroll(e){
e.preventDefault();
}
render(){
return <div
id='child'
style={{position:'fixed',bottom:'100px',width:'70px',height:'70px'}}
onTouchMove={(e)=>{this.onTouchMove(e)}}
onTouchStart={(e)=>{this.onTouchStart(e)}}
onTouchEnd={(e)=>{this.onTouchEnd(e)}}
>
<img style={{width:'100%',height:'100%',pointerEvents:'none'}} src={require('./a.gif')}/>
</div>
}
}
参考资料
- 无
感谢阅读,欢迎评论^-^