- 作者:老汪软件技巧
- 发表时间:2024-12-06 00:09
- 浏览量:
需求: 多页面会用到这个客服icon 点击可以跳转到客服页面,在页面中上滑隐藏 下滑出现实现步骤: 由于客服组件多页面用,需封装起来1. 实现客服icon 的展示1.1. 实现点击可以跳转到客服页面(由于客服链接是一个外部链接,并且之前已经处理过)
import Taro from '@tarojs/taro'
import React, { useEffect, useState } from 'react'
import { View, Text, ScrollView } from '@tarojs/components'
import { HmIcon } from '@/components'
import api from '@/api'
import { showToast } from '@/utils'
import './index.scss'
function HmCustomIcon(props) {
const { size = 48 } = props
const [url, setUrl] = useState('')
useEffect(() => {
getUrl()
}, [])
const getUrl = async () => {
const res = await api.recommend.getLive()
const { url } = res
setUrl(url)
}
const gotoCustom = () => {
// 获取接口数据
if (!url) {
return showToast('客服链接拉取中...')
}
Taro.navigateTo({
url: `/pages/webview?url=${encodeURIComponent(url)}&navigation=show`
})
}
return (
<View className='flex-row flex-align-center flex-justify-center custom' onClick={gotoCustom}>
<HmIcon size={size} value='cs-chat-bubble-cta' className='custom-icon' />
View>
)
}
export default HmCustomIcon
1.2. 跳转外部链接的组件
import React, { useEffect, useRef, useCallback, useState } from 'react'
import Taro, { useRouter } from '@tarojs/taro'
import { useImmer } from 'use-immer'
import { View, WebView } from '@tarojs/components'
import { SpPage } from '@/components'
import EVENTS from '@/consts/events'
import { isAPP, isWeb } from '@/utils'
import { withTranslation, useTranslation } from 'react-i18next'
import './webview.scss'
function WebviewIndex() {
const router = useRouter()
const { t: i18nT } = useTranslation()
const { url, navigation = 'show', title } = router.params
const [dynamicStyle, setDynamicStyle] = useState({})
useEffect(() => {
window.addEventListener('message', (event) => {
if (event.data?.event == EVENTS.EVENT__SHOUQIANBA_PAYRESULT) {
Taro.redirectTo({
url: `/subpages/trade/cashier-result?order_id=${event.data.data?.order_id}`
})
}
})
// console.log(i18nT(decodeURIComponent(title)),'-------------title--------')
}, [])
const st = isAPP() ? 'app' : isWeb ? 'h5' : 'weapp'
return (
<SpPage navigation={navigation == 'show'} className={`page-webview-index page-webview-${st}`}>
<View style={dynamicStyle}>
<WebView src={decodeURIComponent(url)}>WebView>
View>
SpPage>
)
}
export default WebviewIndex
1.3 页面就可以出现一个客服icon 并且点击可以跳转到客服页面
2. 如何实现上滑隐藏,下滑出现呢?
首先想到的是 监听全局的滚动事件 usePageScroll
用usePageScroll 来监听,但是这些用的页面有可能用了scrollview,那么这个监听就失效了
所以这个监听滚动的事件就被pass了
其次,因为我们这个是在移动端,所以我可以监听触摸事件 ontouch
onTouchStart={handleTouchStart}
onTouchMove={handleTouchMove}
onTouchEnd={handleTouchEnd}
于是我在 onTouchMove 中去计算,结果发现这个也会被 scrollview 影响,感觉天崩,但是幸运的是 onTouchStart 和 onTouchEnd 是好的,于是我通过这两个计算可以实现
但是在哪里去做这个监听很重要,如果只是在 客服组件 是实现不了的,需要在一个公共的组件,全局都会用到的里面去做,
于是我选择了在sppage 中处理
sppage 这个是全局公共组件,每个页面都会被它包裹
const [isIconVisible, setIsIconVisible] = useState(true)
const startYRef = useRef(0)
const handleTouchStart = (e) => {
if (!custonIcon) return
startYRef.current = e.touches[0].clientY
// console.log('startYRef', startYRef.current)
}
const handleTouchMove = (e) => {
// if (!custonIcon) return
// const currentY = e.touches[0].clientY // 当前Y坐标
// const deltaY = currentY - startYRef.current // 计算Y轴上的滑动距离
// if (deltaY > 10) {
// // 设定一个阈值来判断滑动是否足够明显
// setIsIconVisible(false) // 向上滑动,隐藏图标
// } else if (deltaY < -10) {
// setIsIconVisible(true) // 向下滑动,显示图标
// }
// console.log('deltaY', deltaY)
}
const handleTouchEnd = (e) => {
if (!custonIcon) return
const endY = e.changedTouches[0].clientY // 获取结束Y坐标
const deltaY = endY - startYRef.current // 计算Y轴上的滑动距离
if (deltaY > 10) {
// 向上滑动,隐藏图标
setIsIconVisible(true)
} else if (deltaY < -10) {
// 向下滑动,显示图标
setIsIconVisible(false)
}
// console.log('endY', endY);
// console.log('deltaY', deltaY);
}
<View
className={classNames(
'sp-page',
`hm-${lang || 'zh'}`,
className,
{
'has-footer': renderFooter,
'has-custom-navigation': customNavigation,
'ipx': state.isIpx
},
`sp-page--${process.env.TARO_ENV}`
)}
style={styleNames({ ...pageTheme, ...lockStyle })}
ref={wrapRef}
onTouchStart={handleTouchStart}
onTouchMove={handleTouchMove}
onTouchEnd={handleTouchEnd}
>
代码省略 ...
{custonIcon && isIconVisible && <HmCustomIcon />}
后续代码省略 ...
以上就完成了