jquery React卷轴bug,适用于纯HTML CSS JS,但不适用于React

chhkpiq4  于 2023-10-17  发布在  jQuery
关注(0)|答案(1)|浏览(107)

我发现了一个很奇怪的小bug。主要的一点是,我试图点击我的.nav li,我希望它会关闭导航栏。如果它在纯HTML CSS和JS上,它会工作,但如果它在React上,它就不工作了。下面是我的React:

import React from 'react';
import Nav from './javascripts/Navigation';
import Ham from './javascripts/Hamburger';
import { Link } from 'react-scroll';
import '../styles/Navbar.scss';

const Navbar = () => {
    React.useEffect(() => {
        Nav();
        Ham();
    }, []);
    return (
        <nav className="nav-container">
                <ul className="nav">
                    <div id="nav-icon">
                        <span></span>
                        <span></span>
                        <span></span>
                        <span></span>
                        <span></span>
                        <span></span>
                    </div>
                    <li>
                        <Link
                            to="container"
                            smooth={true}
                            duration={500}
                            offset={-107}
                        >
                            Home
                        </Link>
                    </li>
                    <li>
                        <Link
                            to="abt-container"
                            smooth={true}
                            duration={500}
                            offset={-107}
                        >
                            About
                        </Link>
                    </li>
                </ul>
        </nav>
    );
};
export default Navbar;

SCSS

$w: #fff;
%nav {
    position: sticky;
    display: flex;
    padding: 15px 30px;
}
%slide {
    position: absolute;
    height: .4rem;
    box-shadow: 1px 1px 0 #666;
    transition: .5s cubic-bezier(.25, 1, .3, 1.05);
    transform: skew(-20deg);
    bottom: 1px;
    height: 100%;
}
.nav-container {
    @extend %nav;
    top: 0;
    justify-content: center;
    background: linear-gradient(110deg, #333 50%, #444 50%);
    z-index: 1;
    .nav {
        @extend %nav;
        list-style: none;
        @media (max-width: 800px) {
            li {
                display: none;
            }
        }
        a {
            position: relative;
            padding: .6em 2em;
            font-size: 20px;
            color: $w;
            display: inline-block;
            text-decoration: none;
            text-shadow: 1px 1px 0 #888;
            z-index: 3;
        }
        .slide1 {
            @extend %slide;
            background-color: #eeeeee30;
            z-index: 2;
        }
        .slide2 {
            @extend %slide;
            opacity: 0;
            background-color: transparent;
            border: 1px solid #fff;
            z-index: 1;
        }
        #nav-icon {
            display: flex;
            justify-content: center;
            width: 50px;
            height: 43px;
            margin: 2px auto;
            transform: rotate(0deg);
            span {
                display: block;
                position: absolute;
                height: 9px;
                width: 50%;
                background: $w;
                opacity: 1;
                transform: rotate(0deg);
                transition: .25s ease-in-out;
                border-radius: 9px;
                &:nth-child(even) {
                    left: 50%;
                    border-radius: 0 9px 9px 0;
                }
                &:nth-child(odd) {
                    left: 0px;
                    border-radius: 9px 0 0 9px;
                }
                &:nth-child(1),
                &:nth-child(2) {
                    top: 0px;
                }
                &:nth-child(3),
                &:nth-child(4) {
                    top: 18px;
                }
                &:nth-child(5),
                &:nth-child(6) {
                    top: 36px;
                }
            }
        }
        #nav-icon.open {
            span {
                &:nth-child(1),
                &:nth-child(6) {
                    transform: rotate(45deg);
                }
                &:nth-child(2),
                &:nth-child(5) {
                    transform: rotate(-45deg);
                }
                &:nth-child(1) {
                    left: 5px;
                    top: 10px;
                }
                &:nth-child(2) {
                    left: calc(50% - 5px);
                    top: 10px;
                }
                &:nth-child(3) {
                    left: -50%;
                    opacity: 0;
                }
                &:nth-child(4) {
                    left: 100%;
                    opacity: 0;
                }
                &:nth-child(5) {
                    left: 5px;
                    top: 24px;
                }
                &:nth-child(6) {
                    left: calc(50% - 5px);
                    top: 24px;
                }
            }
        }
    }
}
li {
    display: none;
}

jQuery

import $ from 'jquery';

const Hamburger = () => {
    let isOpen;
    $(document).on("click", "#nav-icon", function () {
        $(this).toggleClass("open");
        isOpen = !isOpen;
        if (isOpen) {
            $(".nav").css({ display: "block", padding: "15px 0 0 0" });
            $("#nav-icon").css({ paddingBottom: "20px" });
            $("li").css({ display: "block", textAlign: "center" });
        } else {
            $(".nav").css({ padding: "15px 30px" });
            $("#nav-icon").css({ paddingBottom: "0" });
            $("li").css({ display: "none" });
        }
    });
    $(document).on("click", ".nav li", function () {
        if (isOpen) {
            isOpen = false;
            $("#nav-icon").removeClass("open");
            $(".nav").css({ padding: "15px 30px" });
            $("#nav-icon").css({ paddingBottom: "0" });
            $("li").css({ display: "none" });
        }
    });
}
export default Hamburger;

我也尝试了这个代码片段,它工作得很好,但是当我把它放在React上时,它并没有像它应该的那样工作,尽管两个代码都以相同的方式解释。

let isOpen;
    $(document).on("click", "#nav-icon", function () {
        $(this).toggleClass("open");
        isOpen = !isOpen;
        if (isOpen) {
            $(".nav").css({ display: "block", padding: "15px 0 0 0" });
            $("#nav-icon").css({ paddingBottom: "20px" });
            $("li").css({ display: "block", textAlign: "center" });
        } else {
            $(".nav").css({ padding: "15px 30px" });
            $("#nav-icon").css({ paddingBottom: "0" });
            $("li").css({ display: "none" });
        }
    });
    $(document).on("click", ".nav li", function () {
        if (isOpen) {
            isOpen = false;
            $("#nav-icon").removeClass("open");
            $(".nav").css({ padding: "15px 30px" });
            $("#nav-icon").css({ paddingBottom: "0" });
            $("li").css({ display: "none" });
        }
    });
.nav-container .nav, .nav-container {
  position: sticky;
  display: flex;
  padding: 15px 30px;
}

.nav-container .nav .slide2, .nav-container .nav .slide1 {
  position: absolute;
  height: 0.4rem;
  box-shadow: 1px 1px 0 #666;
  transition: 0.5s cubic-bezier(0.25, 1, 0.3, 1.05);
  transform: skew(-20deg);
  bottom: 1px;
  height: 100%;
}

.nav-container {
  top: 0;
  justify-content: center;
  background: linear-gradient(110deg, #333 50%, #444 50%);
  z-index: 1;
}
.nav-container .nav {
  list-style: none;
}
@media (max-width: 800px) {
  .nav-container .nav li {
    display: none;
  }
}
li {
  display: none;
}
.nav-container .nav a {
  position: relative;
  padding: 0.6em 2em;
  font-size: 20px;
  color: #fff;
  display: inline-block;
  text-decoration: none;
  text-shadow: 1px 1px 0 #888;
  z-index: 3;
}
.nav-container .nav .slide1 {
  background-color: rgba(238, 238, 238, 0.1882352941);
  z-index: 2;
}
.nav-container .nav .slide2 {
  opacity: 0;
  background-color: transparent;
  border: 1px solid #fff;
  z-index: 1;
}
.nav-container .nav #nav-icon {
  display: flex;
  justify-content: center;
  width: 50px;
  height: 43px;
  margin: 2px auto;
  transform: rotate(0deg);
}
.nav-container .nav #nav-icon span {
  display: block;
  position: absolute;
  height: 9px;
  width: 50%;
  background: #fff;
  opacity: 1;
  transform: rotate(0deg);
  transition: 0.25s ease-in-out;
  border-radius: 9px;
}
.nav-container .nav #nav-icon span:nth-child(even) {
  left: 50%;
  border-radius: 0 9px 9px 0;
}
.nav-container .nav #nav-icon span:nth-child(odd) {
  left: 0px;
  border-radius: 9px 0 0 9px;
}
.nav-container .nav #nav-icon span:nth-child(1), .nav-container .nav #nav-icon span:nth-child(2) {
  top: 0px;
}
.nav-container .nav #nav-icon span:nth-child(3), .nav-container .nav #nav-icon span:nth-child(4) {
  top: 18px;
}
.nav-container .nav #nav-icon span:nth-child(5), .nav-container .nav #nav-icon span:nth-child(6) {
  top: 36px;
}
.nav-container .nav #nav-icon.open span:nth-child(1), .nav-container .nav #nav-icon.open span:nth-child(6) {
  transform: rotate(45deg);
}
.nav-container .nav #nav-icon.open span:nth-child(2), .nav-container .nav #nav-icon.open span:nth-child(5) {
  transform: rotate(-45deg);
}
.nav-container .nav #nav-icon.open span:nth-child(1) {
  left: 5px;
  top: 10px;
}
.nav-container .nav #nav-icon.open span:nth-child(2) {
  left: calc(50% - 5px);
  top: 10px;
}
.nav-container .nav #nav-icon.open span:nth-child(3) {
  left: -50%;
  opacity: 0;
}
.nav-container .nav #nav-icon.open span:nth-child(4) {
  left: 100%;
  opacity: 0;
}
.nav-container .nav #nav-icon.open span:nth-child(5) {
  left: 5px;
  top: 24px;
}
.nav-container .nav #nav-icon.open span:nth-child(6) {
  left: calc(50% - 5px);
  top: 24px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class="nav-container">
                <ul class="nav">
                    <div id="nav-icon">
                        <span></span>
                        <span></span>
                        <span></span>
                        <span></span>
                        <span></span>
                        <span></span>
                    </div>
                    <li>
                        <a>
                            Home
                        </a>
                    </li>
                    <li>
                        <a>
                            About
                        </a>
                    </li>
                </ul>
        </nav>
brqmpdu1

brqmpdu11#

这不是React bug。这种行为的原因在于“链接”的实现。当“Link”处理点击事件时,它停止事件传播。因此,您的处理程序不会被触发。
要解决这个问题,您可以将自己的单击处理程序作为“onClick”属性传递给“Link”组件。这个点击处理程序也可以用jQuery编写,因此您可以使用现有的代码
食谱:
1.将现有的jQuery点击处理程序移动到一个单独的函数中

import $ from "jquery";

export function closeNavbar() {
 $("#nav-icon").removeClass("open");
 $(".nav").css({ padding: "15px 30px" });
 $("#nav-icon").css({ paddingBottom: "0" });
 $("li").css({ display: "none" });
}

1.将此函数作为“onClick”属性传递给“Link”组件

<nav className="nav-container">
      <ul className="nav">
        <div id="nav-icon">
          ...
        </div>
        <li>
          <Link
            onClick={() => closeNavbar()}
            ...
          >
            Home
          </Link>
        </li>
      </ul>
    </nav>

相关问题