• 作者:老汪软件技巧
  • 发表时间: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 />}
      
     后续代码省略 ...

以上就完成了