亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

react實(shí)現(xiàn)阻止父容器滾動(dòng)

 更新時(shí)間:2023年11月14日 10:07:56   作者:天天向上的鹿茸  
這篇文章主要介紹了react實(shí)現(xiàn)阻止父容器滾動(dòng)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

react阻止父容器滾動(dòng)

最近在做代碼遷移的時(shí)候出現(xiàn)一個(gè)問(wèn)題,發(fā)現(xiàn)之前自己寫(xiě)好的一個(gè)自定義滾動(dòng)條組件有個(gè)bug,那就滾動(dòng)時(shí)父容器也會(huì)滾動(dòng)。

看一下代碼,代碼做了簡(jiǎn)化

export default ()=>{
return return (
    <div
      className={classNames(getCls('container'), isDragRef.current ? 'active' : '', className)}
      ref={scrollDOMRef}
      onWheelCapture={(e: any) => {
        e.preventDefault();
        if (e.deltaY < 0) {
          // 向上
          setDragY(dragY - dragSpeed);
        } else {
          // 向下
          setDragY(dragY + dragSpeed);
        }
      }}>
    </div>
  );
}

既然父容器會(huì)滾動(dòng)那就阻止默認(rèn)行為就好e.preventDefault();,但是沒(méi)用。

這里我猜測(cè)應(yīng)該因?yàn)閞eact的事件是合成事件的緣故,所有事件都注冊(cè)document上,所以導(dǎo)致阻止的默認(rèn)行為并沒(méi)有阻止到父容器上。

那就用原生的唄。

useEffect(() => {
    if (scrollDOMRef.current) {
      scrollDOMRef.current.addEventListener('wheel', (e) => {
        e.preventDefault();
        if (e.deltaY < 0) {
          // 向上
          setDragY(dragY - dragSpeed);
        } else {
          // 向下
          setDragY(dragY + dragSpeed);
        }
      });
    }
  }, [scrollDOMRef.current]);

原生事件和react事件一起用時(shí)要注意,阻止冒泡要考慮清楚,因?yàn)榭赡軙?huì)導(dǎo)致react合成事件失效。

那這么做后就可以了嗎?

確實(shí)

父容器不滾動(dòng)了

但是又掉進(jìn)了react的閉包陷阱

注冊(cè)函數(shù)并沒(méi)有及時(shí)更新,dragY 和 dragSpeed的閉包導(dǎo)致出現(xiàn)了bug。

那么又應(yīng)該怎么做呢?

useEffect(() => {
    if (scrollDOMRef.current) {
      scrollDOMRef.current.addEventListener('wheel', (e) => {
        e.preventDefault();
        if (e.deltaY < 0) {
          // 向上
          setDragY(dragY - dragSpeed);
        } else {
          // 向下
          setDragY(dragY + dragSpeed);
        }
      });
    }
  }, [scrollDOMRef.current, dragY, dragSpeed]);

又一個(gè)問(wèn)題出現(xiàn)了

每次應(yīng)該把之前的事件銷(xiāo)毀,然后在注冊(cè)才對(duì)。

不然多個(gè)事件同時(shí)觸發(fā)導(dǎo)致了bug。

useEffect(() => {
    const handle = (e: any) => {
      e.preventDefault();
      if (e.deltaY < 0) {
        // 向上
        setDragY(dragY - dragSpeed);
      } else {
        // 向下
        setDragY(dragY + dragSpeed);
      }
    };
    if (scrollDOMRef.current) {
      scrollDOMRef.current.addEventListener('wheel', handle, {
        passive: false,
      });
    }
    return () => {
      if (scrollDOMRef.current) {
        scrollDOMRef.current.removeEventListener('wheel', handle);
      }
    };
  }, [scrollDOMRef.current, dragY, dragSpeed]);

passive

passive為false時(shí),瀏覽器執(zhí)行完回調(diào)函數(shù)才知道有沒(méi)有調(diào)用preventDefault,如果沒(méi)有調(diào)用preventDefault,再去執(zhí)行默認(rèn)行為,就是滾動(dòng)。這樣就回造成滾動(dòng)不流暢。

passive為true,就是告訴瀏覽器不會(huì)調(diào)用preventDefault,瀏覽器直接執(zhí)行滾動(dòng)就行,不用考慮回調(diào)函數(shù)了。

這時(shí),即使你在回調(diào)函數(shù)里調(diào)用preventDefault也不會(huì)生效。

mdn中說(shuō),在有些瀏覽器(特別是Chrome和Firefox)中,你監(jiān)聽(tīng)window、document或者document.body上的touchstart和touchmove,會(huì)將passive默認(rèn)設(shè)置為true。

還是要提醒大家,在你不需要調(diào)用preventDefault的時(shí)候,監(jiān)聽(tīng)scroll或者touchmove,將passive設(shè)置為true

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • React實(shí)現(xiàn)原生APP切換效果

    React實(shí)現(xiàn)原生APP切換效果

    最近需要使用 Hybrid 的方式開(kāi)發(fā)一 個(gè) APP,交互和原生 APP 相似并且需要 IM 通信,本文給大家介紹了使用React實(shí)現(xiàn)原生APP切換效果,文中通過(guò)代碼示例講解的非常詳細(xì),感興趣的小伙伴跟著小編一起來(lái)看看吧
    2025-01-01
  • React可定制黑暗模式切換開(kāi)關(guān)組件

    React可定制黑暗模式切換開(kāi)關(guān)組件

    這篇文章主要為大家介紹了React可定制黑暗模式切換開(kāi)關(guān)組件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • react中實(shí)現(xiàn)拖拽排序react-dnd功能

    react中實(shí)現(xiàn)拖拽排序react-dnd功能

    這篇文章主要介紹了react中實(shí)現(xiàn)拖拽排序react-dnd功能,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-02-02
  • React中使用Workbox進(jìn)行預(yù)緩存的實(shí)現(xiàn)代碼

    React中使用Workbox進(jìn)行預(yù)緩存的實(shí)現(xiàn)代碼

    Workbox是Google Chrome團(tuán)隊(duì)推出的一套 PWA 的解決方案,這套解決方案當(dāng)中包含了核心庫(kù)和構(gòu)建工具,因此我們可以利用Workbox實(shí)現(xiàn)Service Worker的快速開(kāi)發(fā),本文小編給大家介紹了React中使用Workbox進(jìn)行預(yù)緩存的實(shí)現(xiàn),需要的朋友可以參考下
    2023-11-11
  • React組件的生命周期詳解

    React組件的生命周期詳解

    React是用于構(gòu)建用戶(hù)界面的JavaScript庫(kù)。本文詳細(xì)講解了React的生命周期,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • 從頭寫(xiě)React-like框架的工程搭建實(shí)現(xiàn)

    從頭寫(xiě)React-like框架的工程搭建實(shí)現(xiàn)

    這篇文章主要介紹了從頭寫(xiě)React-like框架的工程搭建實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • React 中常用的幾種路由跳轉(zhuǎn)方式小結(jié)

    React 中常用的幾種路由跳轉(zhuǎn)方式小結(jié)

    基本路由跳轉(zhuǎn)是最常見(jiàn)的一種方式,下面介紹React 中常用的幾種路由跳轉(zhuǎn)方式,感興趣的朋友一起看看吧
    2023-12-12
  • React動(dòng)畫(huà)實(shí)現(xiàn)方案Framer Motion讓頁(yè)面自己動(dòng)起來(lái)

    React動(dòng)畫(huà)實(shí)現(xiàn)方案Framer Motion讓頁(yè)面自己動(dòng)起來(lái)

    這篇文章主要為大家介紹了React動(dòng)畫(huà)實(shí)現(xiàn)方案Framer Motion讓頁(yè)面自己動(dòng)起來(lái),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • 詳解webpack2+React 實(shí)例demo

    詳解webpack2+React 實(shí)例demo

    本篇文章主要介紹了詳解webpack2+React 實(shí)例demo,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • React state狀態(tài)屬性用法講解

    React state狀態(tài)屬性用法講解

    React將組件(component)看成一個(gè)狀態(tài)機(jī)(State Machines),通過(guò)其內(nèi)部自定義的狀態(tài)(State)和生命周期(Lifecycle)實(shí)現(xiàn)并與用戶(hù)交互,維持組件的不同狀態(tài)
    2022-11-11

最新評(píng)論