最新更新時間: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>
}
}
參考資料
- 無
感謝閱讀,歡迎評論^-^