【问题标题】:React scroll to top animation button does not work反应滚动到顶部动画按钮不起作用
【发布时间】:2020-06-19 09:15:48
【问题描述】:

我尝试在 React 上实现 jquery 按钮单击滚动到顶部。我也想实现这个按钮,它出现在 400px 之后。我尝试了逻辑,但似乎按钮单击不起作用。

这是我的 React 组件

import React from "react";
import { createLogEntry } from "./Api";
import Show from "./Show";
export default function Form() {
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState("");
  const [state, setState] = React.useState({
    name: " ",
    description: " "
  });

  const changeHandler = e => {
    setState({ ...state, [e.target.id]: e.target.value });
  };
  const handleSubmit = async e => {
    e.preventDefault();
    setLoading(true);
    try {
      await createLogEntry({
        name: state.name,
        description: state.description
      });
    } catch (error) {
      setError(error.message);
    }
    setLoading(false);
    setState({ name: " ", description: " " });
  };
  return (
    <React.Fragment>
      <div className="app">
        <button className="btnScrollToTop"> //THIS IS MY SCROLL BUTTON
          <i className="material-icons">arrow_upward</i>
        </button>
        <div className="row">
          <form className="col s12" onSubmit={handleSubmit}>
            {error ? <p className="error">{error}</p> : null}
            <div className="row">
              <div className="input-field col s3">
                <input
                  id="name"
                  type="text"
                  data-length="4"
                  onChange={changeHandler}
                  required
                  value={state.name}
                />
                <label htmlFor="input_text">Topic</label>
              </div>
            </div>
            <div className="row">
              <div className="input-field col s8">
                <textarea
                  id="description"
                  className="materialize-textarea"
                  data-length="120"
                  onChange={changeHandler}
                  required
                  value={state.description}
                ></textarea>
                <label htmlFor="textarea2">Description</label>
              </div>
            </div>
            <button
              className="btn waves-effect blue lighten-1"
              type="submit"
              name="action"
              disabled={loading}
            >
              {loading ? "Loading..." : "Create Entry"}
            </button>
          </form>
        </div>
      </div>
      <Show />
    </React.Fragment>
  );
}

这是 Css。正如预期的那样,Css 样式工作正常。

.btnScrollToTop {
  position: fixed;
  right: 10px;
  bottom: 10px;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background: #e62739;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.25);
  color: #ffffff;
  border: none;
  outline: none;
  cursor: pointer;
}
.btnScrollToTop:active {
  background: #cc2333;
}

这是 React 的 index.html 文件。我认为问题出在此处。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"
    />

    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <link
      href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet"
    />
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script>
      const btnScrollToTop = document.getElementsByClassName(".btnScrollToTop"); //HERE I called the button className from the component and below DOM manipulation.
      btnScrollToTop.addEventListener("click", () => {
        window.scrollTo({
          top: 0,
          left: 0,
          behavior: "smooth"
        });
      });
    </script>
  </body>
</html>

【问题讨论】:

  • 你能用代码给我看看吗?

标签: jquery css reactjs scroll


【解决方案1】:

既然你用的是materialize,那你为什么不使用内置的scrollspy呢?

要滚动到的元素:

<div id="header" class="scrollspy">
   ...
</div>

在目标 div 上,我们分配一个 ID 作为目标和一个 scrollspy 类来获得流畅的动画。

滚动触发:

<a href="#header">Scroll to trigger!</a>

初始化:

document.addEventListener('DOMContentLoaded', function() {
    var elems = document.querySelectorAll('.scrollspy');
    var instances = M.ScrollSpy.init(elems);
  });

https://materializecss.com/scrollspy.html

【讨论】:

  • 谢谢@Sean。但我不知道,我应该在哪里使用基于我的 React 组件的 scrollspy?
【解决方案2】:

除了使用 getElementsByClassName 之外,只需将侦听器添加到所有类并将其放入 document.ready 函数中。

$(document).ready(function() {
    $(".btnScrollToTop").addEventListener("click", () => {
        window.scrollTo({
          top: 0,
          left: 0,
          behavior: "smooth"
        });
      });
});

【讨论】:

  • 你不能附加到你的dom中的按钮,因为react使用它自己的虚拟dom,所以必须通过它来完成。
猜你喜欢
  • 2017-07-20
  • 1970-01-01
  • 2021-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-26
相关资源
最近更新 更多