欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React?實(shí)現(xiàn)具備吸頂和吸底功能組件實(shí)例

 更新時(shí)間:2023年02月23日 12:00:01   作者:Hutao  
這篇文章主要為大家介紹了React?實(shí)現(xiàn)具備吸頂和吸底功能組件實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

背景

現(xiàn)在手機(jī)應(yīng)用經(jīng)常有這樣一個(gè)場景:

頁面上有一個(gè)導(dǎo)航,導(dǎo)航位置在頁面中間位置,當(dāng)頁面頂部滾動(dòng)到導(dǎo)航位置時(shí),導(dǎo)航自動(dòng)吸頂,頁面繼續(xù)往下滾動(dòng)時(shí),它就一直在頁面視窗頂部顯示,當(dāng)往上滾動(dòng)時(shí),經(jīng)過最初位置時(shí),導(dǎo)航自動(dòng)復(fù)原,不再吸頂。

效果就如京東超市首頁的導(dǎo)航欄一樣:

下面我們就來具體實(shí)現(xiàn)這樣一個(gè) React 組件,實(shí)現(xiàn)后還會(huì)再擴(kuò)展延伸一下 吸底 功能,因?yàn)?吸底 場景也不少。

具體要求:

  • 需要可以設(shè)置是 吸頂 還是 吸底
  • 吸頂 可以設(shè)置距離視窗頂部的位置,吸頂 可以設(shè)置距離視窗底部的位置。
  • 可以對正常組件都生效,不影響組件自身的樣式。

實(shí)現(xiàn)

組件主要是為了 吸頂 或者 吸底 功能,那么就命名為 AutoFixed

主要實(shí)現(xiàn)邏輯:需要判斷自身在視窗內(nèi)的位置與設(shè)置的 吸頂 或者 吸底 位置是否匹配,匹配上了則可以進(jìn)行 吸頂 或者 吸底

獲取自身位置一般可以用 滾動(dòng)的位置自身距離頁面頂部 的位置來判斷,但實(shí)現(xiàn)起來會(huì)麻煩一些,IntersectionObserver也很好用,而且性能會(huì)更好,因此這里將直接使用 IntersectionObserver 來處理。

下面,我們先實(shí)現(xiàn)一個(gè)基于 IntersectionObserver 實(shí)現(xiàn)的判斷位置的 hook

定義 props 類型:

import { RefObject } from "react";
type Props = {
  el: React.RefObject<Element>;
  options?: IntersectionObserverInit;
};

可接受參數(shù):

el: React 的 ref 實(shí)例,被判斷判斷位置的 DOM 元素。 options: IntersectionObserver 構(gòu)造函數(shù)的初始化參數(shù)。

具體實(shí)現(xiàn):

import React, { useEffect, useState } from "react";
export function useIntersection(props: Props): boolean {
  const { el, options } = props;
  // 是否到了指定位置區(qū)域
  const [intersection, setIntersection] = useState(true);
  useEffect(() => {
    if (!el.current) return;
    // 初始化 IntersectionObserver 實(shí)例
    const intersectionObserver = new IntersectionObserver(
      function (entries) {
        setIntersection(entries[0].intersectionRatio === 1);
      },
      { ...options, threshold: [1] }
    );
    // 開始監(jiān)聽
    intersectionObserver.observe(el.current);
    return (): void => {
      // 銷毀
      intersectionObserver.disconnect();
    };
  }, [el.current]);
  return intersection;
}

現(xiàn)在實(shí)現(xiàn)了一個(gè)可以根據(jù)傳入的參數(shù)來控制否到了指定位置區(qū)域的 hook :useIntersection。

useIntersection 只是對 IntersectionObserver 的簡單封裝,并沒有復(fù)雜實(shí)現(xiàn),具體作用就是用于判斷某個(gè)元素是否進(jìn)入了 可視窗口,想了解更多可以點(diǎn)擊去查看它的MDN文檔。

下面再來實(shí)現(xiàn)我們要實(shí)現(xiàn)的具備吸頂和吸底功能的組件:AutoFixed

參數(shù)定義:

export type AutoFixedProps = React.ImgHTMLAttributes<HTMLDivElement> & {
  /** 吸頂距離 */
  top?: string;
  /** 吸底距離 */
  bottom?: string;
  /** 是否一直吸頂或者吸底 */
  alwaysFixed?: boolean;
  zIndex?: number;
  children: React.ReactNode;
  /** 元素框高度 */
  height: number | string;
  /** 相對的目標(biāo)元素,因?yàn)槭怯玫?fixed 定位,記得做相應(yīng)處理。 */
  root?: Element | Document | null;
  /** 固定的時(shí)候才有的className */
  fixedClassName?: string;
  /** 固定的時(shí)候才有的樣式 */
  fixedStyle?: React.CSSProperties;
  /** fixed狀態(tài)改變時(shí)調(diào)用 */
  onFixedChange?: (isFixed: boolean) => void;
};

可接受參數(shù) 基于 React.HtmlHTMLAttributes<HTMLDivElement> ,也就是繼承了 div 的默認(rèn)屬性。

其他自定義參數(shù)說明:

  • top 吸頂距離,元素頂部距離視窗頂部小于等于 top 時(shí),進(jìn)行吸頂。
  • bottom 吸底部距離,元素底部距離視窗底部大于等于 bottom 時(shí),進(jìn)行吸底。注意邏輯是和吸頂相反。
  • alwaysFixed,用于支持默認(rèn)就要一直吸頂或者吸底的情況,需要配合 topbottom 來使用。
  • zIndex 控制吸頂或者吸底時(shí)的樣式層級(jí)。
  • children children 元素是正常的 React 組件即可。
  • height 被包裹元素的高度.也就是 children 元素 的高度。
  • root,相對視窗的目標(biāo)元素,也就是可以控制在某個(gè)區(qū)域內(nèi)進(jìn)行吸頂和吸底,但因?yàn)檫@里是用的 fixed 定位,如果需要設(shè)置 root 時(shí),需要改變成 absolute 定位。
  • fixedClassName 吸頂和吸底的時(shí)候需要?jiǎng)討B(tài)添加的 className。
  • fixedStyle 吸頂和吸底的時(shí)候需要?jiǎng)討B(tài)添加的 樣式。
  • onFixedChange 吸頂和吸底的時(shí)候告訴外界。

具體實(shí)現(xiàn):

import React, { useRef, useEffect } from "react";
import { useIntersection } from "../../components/hooks/use-intersection";
export const AutoFixed = (props: AutoFixedProps) => {
  const {
    alwaysFixed,
    top,
    bottom,
    style,
    height,
    root,
    zIndex = 100,
    children,
    className,
    fixedClassName,
    fixedStyle,
    onFixedChange,
    ...rest
  } = props;
  // `bottom` 值存在時(shí),表面要懸浮底部
  const isFiexdTop = !bottom;
  const wrapperRef = useRef<HTMLDivElement>(null);
  // 設(shè)置監(jiān)聽參數(shù)控制:top 為吸頂距離,bottom 為吸底距離
  const options = {
    rootMargin: isFiexdTop
      ? `-${top || "0px"} 0px 1000000px 0px`
      : `0px 0px -${bottom || "0px"} 0px`,
    // 設(shè)置root
    root,
  } as IntersectionObserverInit;
  // 是否懸浮
  const intersection = useIntersection({ el: wrapperRef, options });
  const shouldFixed = alwaysFixed ? true : !intersection;
  useEffect(() => {
    // 通知外部
    onFixedChange?.(shouldFixed);
  }, [shouldFixed, onFixedChange]);
  return (
    <div
      style={{ ...style, height }}
      {...rest}
      className={`${className}${shouldFixed ? " fixedClassName" : ""}`}
      ref={wrapperRef}
    >
      <div
        style={{
          height,
          position: shouldFixed ? "fixed" : "initial",
          top: isFiexdTop ? top || 0 : undefined,
          bottom: isFiexdTop ? undefined : bottom || 0,
          zIndex: zIndex,
          ...(shouldFixed ? fixedStyle : {}),
        }}
      >
        {children}
      </div>
    </div>
  );
};

實(shí)現(xiàn)邏輯:

  • 使用了 alwaysFixed 判斷是否一直懸浮。
  • 默認(rèn)懸浮頂部,bottom 值存在時(shí),表明要懸浮底部。
  • useIntersection 傳入監(jiān)聽位置控制參數(shù)。
  • 根據(jù) useIntersection 的結(jié)果來判斷是否應(yīng)該 吸頂吸底 。
  • 做了 style 樣式和 className 傳入處理的問題,以及 zIndex 層級(jí)問題。
  • 吸頂時(shí),不進(jìn)行設(shè)置 bottom,吸底時(shí),不進(jìn)行設(shè)置 bottom。

主要核心邏輯是第 3 點(diǎn):

const options = {
    rootMargin: `-${top || "0px"} 0px -${bottom || "0px"} 0px`,
};

rootMargin 中:-${top || "0px"} 為吸頂距離,-${bottom || "0px"} 為吸底距離。一定要是負(fù)的,正數(shù)表示延伸到了視窗外的距離,負(fù)數(shù)表示距離視窗頂部或者底部的距離。

使用方式:

<AutoFixed
    // 距離頂部為 20px 吸頂
    top="20px"
    // 占位高度,也就是 children 的高度
    height="20px"
    // fixed狀態(tài)改變時(shí)
    onFixedChange={(isFixed) => {
      console.log(`isFixed: ` + isFixed);
    }}
    // fixed狀態(tài)需要添加的className
    fixedClassName="hello"
    // fixed狀態(tài)需要添加的style
    fixedStyle={{ color: "red" }}
>
    <div>
        我是懸浮內(nèi)容,高度 20px, 距離頂部為 20px 吸頂
    </div>
</AutoFixed>

實(shí)現(xiàn)效果:

可以看出 一直吸頂 、滾動(dòng)到設(shè)定位置吸頂一直吸底 、滾動(dòng)到設(shè)定位置吸底 四個(gè)功能都可以正常工作。

滾動(dòng)到設(shè)定位置吸底 指的是,從底部向上滾動(dòng)的時(shí)候,這個(gè)功能就是為了在劃出屏幕區(qū)域的時(shí)候顯示在底部。

大家也可以打開 示例 自己去體驗(yàn)一下。

結(jié)語

這是之前在比較多的頁面會(huì)用到的一個(gè)功能點(diǎn),然后寫了幾次后,發(fā)現(xiàn)每次實(shí)現(xiàn)這個(gè)功能都有點(diǎn)復(fù)雜,于是封裝了 吸頂 組件,本次寫文章,就想著剛好可以完善一下,把 吸底 功能也開發(fā)出來,因?yàn)楹罄m(xù)也有用到過不少次。

以上就是React 實(shí)現(xiàn)具備吸頂和吸底功能組件實(shí)例的詳細(xì)內(nèi)容,更多關(guān)于React吸頂吸底功能的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React?Native采用Hermes熱更新打包方案詳解

    React?Native采用Hermes熱更新打包方案詳解

    這篇文章主要介紹了React?Native采用Hermes熱更新打包實(shí)戰(zhàn),在傳統(tǒng)的熱更新方案中,我們實(shí)現(xiàn)熱更新需要借助code-push開源方案,包括熱更新包的發(fā)布兩種方式詳解,感興趣的朋友一起看看吧
    2022-05-05
  • React?Hooks useReducer?逃避deps組件渲染次數(shù)增加陷阱

    React?Hooks useReducer?逃避deps組件渲染次數(shù)增加陷阱

    這篇文章主要介紹了React?Hooks?之?useReducer?逃避deps后增加組件渲染次數(shù)的陷阱詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • React Native中NavigatorIOS組件的簡單使用詳解

    React Native中NavigatorIOS組件的簡單使用詳解

    這篇文章主要介紹了React Native中NavigatorIOS組件的簡單使用詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-01-01
  • React中setState同步異步場景的使用

    React中setState同步異步場景的使用

    本文主要介紹了React中setState同步異步場景的使用,文中根據(jù)實(shí)例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • React?狀態(tài)管理工具優(yōu)劣勢示例分析

    React?狀態(tài)管理工具優(yōu)劣勢示例分析

    這篇文章主要為大家介紹了React?狀態(tài)管理工具優(yōu)劣勢示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • React Native自定義控件底部抽屜菜單的示例

    React Native自定義控件底部抽屜菜單的示例

    本篇文章主要介紹了React Native自定義控件底部抽屜菜單的示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-02-02
  • React合成事件原理解析

    React合成事件原理解析

    事件是在編程時(shí)系統(tǒng)內(nèi)發(fā)生的動(dòng)作或者發(fā)生的事情,而開發(fā)者可以某種方式對事件做出回應(yīng),而這里有幾個(gè)先決條件,這篇文章主要介紹了React合成事件原理解析,需要的朋友可以參考下
    2022-07-07
  • 詳解React中的useMemo和useCallback的區(qū)別

    詳解React中的useMemo和useCallback的區(qū)別

    React中的useMemo和useCallback是兩個(gè)重要的Hooks。常常被用于優(yōu)化組件的性能。雖然這兩個(gè)Hooks看起來很相似,但它們彼此之間還是有很大的區(qū)別的,隨著小編一起來學(xué)習(xí)吧
    2023-04-04
  • React如何利用Antd的Form組件實(shí)現(xiàn)表單功能詳解

    React如何利用Antd的Form組件實(shí)現(xiàn)表單功能詳解

    這篇文章主要給大家介紹了關(guān)于React如何利用Antd的Form組件實(shí)現(xiàn)表單功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • React學(xué)習(xí)筆記之列表渲染示例詳解

    React學(xué)習(xí)筆記之列表渲染示例詳解

    最近在學(xué)習(xí)React,學(xué)習(xí)到了列表渲染這一塊,發(fā)現(xiàn)網(wǎng)上這方面的資料較少,所以自己來總結(jié)下,下面這篇文章主要給大家介紹了關(guān)于React學(xué)習(xí)筆記之列表渲染的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-08-08

最新評論