滚动到页面顶部时底部栏不可见

问题描述 投票:0回答:1

我有一个底部栏的 React 组件,它应该根据滚动方向和位置切换其可见性。尽管将滚动设置为 0,但当向上滚动或在页面顶部时,底部栏不会始终显示在移动设备上。

import { useEffect, useState } from 'react';
import {
  BsHeartFill,
  BsFillPersonFill,
  BsFillBasket2Fill,
  BsCart2,
} from 'react-icons/bs';
import { Link, useLocation } from 'react-router-dom';
import { AiFillHome } from 'react-icons/ai';
import { IoIosCube } from 'react-icons/io';
import CategorySVG from './SVGS/CategorySVG';
import useUser from './hooks/useUser';
import { useDispatch } from 'react-redux';
import { success } from '../common/Common.Action';

export default function BottomBar({
  data,
  onMoveWhishListItem,
  handleClick,
  addCart,
  foundCartProduct,
  itemChecked,
  addProductToCart,
  handleCheckout,
  buyProduct,
}) {
  const [scrollDirection, setScrollDirection] = useState('up');
  const [bottomBarVisible, setBottomBarVisible] = useState(true);
  const { isAuthenticated } = useUser();
  const location = useLocation();
  const dispatch = useDispatch();

  const productDetailsSlug = location.pathname.includes('product-details');

  useEffect(() => {
    let prevScrollY = window.scrollY;

    const handleScroll = () => {
      const currentScrollY = window.scrollY;

      if (currentScrollY > prevScrollY) {
        setScrollDirection('down');
      } else {
        setScrollDirection('up');
      }

      if (scrollDirection === 'down') {
        setBottomBarVisible(false);
      } else if (currentScrollY === 0) {
        setBottomBarVisible(true);
      } else {
        setBottomBarVisible(true);
      }

      prevScrollY = currentScrollY;
    };

    window.addEventListener('scroll', handleScroll);

    return () => {
      window.removeEventListener('scroll', handleScroll);
    };
  }, [scrollDirection]);

  return (
    <>
      {!productDetailsSlug ? (
        <div
          className={`bg-white h-16 z-20 text-gray-700 fixed bottom-0 left-0 right-0 max-w-screen md:hidden flex justify-center items-center ${
            !bottomBarVisible ? 'bottom-bar hidden' : ''
          }`}
        >
          <div className="flex justify-between items-center w-full px-4">
            <Link
              to="/"
              className={`flex flex-col items-center ${
                location.pathname === '/' ? 'text-[#ec6525]' : ''
              }`}
            >
              <AiFillHome size={25} />
              <p className="text-[12px] font-medium">Home</p>
            </Link>
            <Link
              className={`flex flex-col items-center ${
                location.pathname === '/all-category' ? 'text-[#ec6525]' : ''
              }`}
              to="/all-category"
            >
              <CategorySVG />
              <p className="text-[12px] font-medium">Categories</p>
            </Link>
            {!isAuthenticated ? (
              <Link
                to="/login"
                className={`flex flex-col items-center ${
                  location.pathname === '/login' ? 'text-[#ec6525]' : ''
                }`}
                state={{ prev: '/' }}
              >
                <BsFillPersonFill size={25} />
                <p className="text-[12px] font-medium">Account</p>
              </Link>
            ) : (
              <Link
                to="/account"
                className={`flex flex-col items-center ${
                  location.pathname === '/account' ? 'text-[#ec6525]' : ''
                }`}
              >
                <BsFillPersonFill size={25} />
                <p className="text-[12px] font-medium">Account</p>
              </Link>
            )}

            {isAuthenticated && (
              <>
                <Link
                  to="/wishlist"
                  className={`flex flex-col items-center ${
                    location.pathname === '/wishlist' ? 'text-[#ec6525]' : ''
                  }`}
                >
                  <BsHeartFill size={25} />
                  <p className="text-[12px] font-medium">Wishlist</p>
                </Link>

                <Link
                  to="/order-history"
                  className={`flex flex-col items-center ${
                    location.pathname === '/order-history'
                      ? 'text-[#ec6525]'
                      : ''
                  }`}
                >
                  <IoIosCube size={25} />
                  <p className="text-[12px] font-medium">Orders</p>
                </Link>
              </>
            )}
          </div>
        </div>
      ) : (
        <ul className="bg-white h-16 z-20 text-gray-700 fixed bottom-0 left-0 right-0 max-w-screen md:hidden flex gap-2 justify-around items-center">
          <li onClick={() => onMoveWhishListItem(data)}>
            {!isAuthenticated ? (
              <button
                className="border border-gray-300 px-4 py-3 rounded-lg"
                onClick={handleClick}
              >
                <BsHeartFill className="text-gray-600" size={20} />
              </button>
            ) : (
              <button className="border border-gray-300 px-4 py-3 rounded-lg">
                {data?.isFavorite ? (
                  <BsHeartFill className="text-pink-500" size={20} />
                ) : (
                  <BsHeartFill className="text-gray-600" size={20} />
                )}
              </button>
            )}
          </li>
          <li className="w-40">
            {addCart === false && !foundCartProduct ? (
              <button
                onClick={() => {
                  if (itemChecked) {
                    addProductToCart(data);
                  } else {
                    dispatch(success('Select Variant First'));
                  }
                }}
                className="bg-[#FF9F00] w-full text-white font-medium px-2 py-3 rounded-lg flex items-center justify-center gap-1"
              >
                <BsFillBasket2Fill />
                Add To Cart
              </button>
            ) : (
              <Link
                to="/cart"
                className="bg-[#FF9F00] w-full text-white font-medium px-2 py-3 rounded-lg flex items-center justify-center gap-1"
              >
                <BsFillBasket2Fill />
                GO TO CART
              </Link>
            )}
          </li>
          <li className="w-40">
            {isAuthenticated && data?.stock > 0 ? (
              <button
                className="bg-[#FB641B] flex items-center justify-center w-full text-white font-medium px-2 py-3 rounded-lg gap-1"
                onClick={() => {
                  if (itemChecked) {
                    buyProduct(data);
                  } else {
                    dispatch(success('Select Variant First'));
                  }
                }}
              >
                <BsCart2 />
                BUY NOW
              </button>
            ) : (
              <button
                className="bg-[#FB641B] flex items-center justify-center w-full text-white font-medium px-2 py-3 rounded-lg gap-1"
                onClick={handleCheckout}
              >
                <BsCart2 />
                BUY NOW
              </button>
            )}
          </li>
        </ul>
      )}
    </>
  );
}

在真实的移动设备上进行测试时,底部栏并不总是出现,尽管逻辑设置为在向上滚动或在页面顶部时显示底部栏。可见性切换似乎没有按预期工作,尽管将滚动设置为 0,但底部栏在移动设备上仍然隐藏。

我希望获得有关如何确保当滚动位于顶部或向上滚动时底部栏按预期在移动设备上显示的指导或建议,根据在 useEffect 中为 handleScroll 实现的逻辑。

如果有人遇到类似的问题或对在移动设备的 React 中处理滚动事件有深入的了解,我们将非常感谢您的意见或建议。

javascript reactjs tailwind-css bottomnavigationview
1个回答
0
投票

我不太喜欢利用滚动事件并进行手动计算。它总是容易出错,因此现代浏览器提供了一个新的 API 来处理这个问题:https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

查看那里的示例,并查看 this npm package for React。

© www.soinside.com 2019 - 2024. All rights reserved.