【问题标题】:How can I make this element class change on scroll in React?如何在 React 中滚动时更改此元素类?
【发布时间】:2019-06-14 16:04:13
【问题描述】:

当您在元素上方滚动 100 像素或更少时,我希望 div 元素获得“showtext”类。当您高于它 100 像素或更多时,它具有“隐藏”类。

我正在尝试使用 ref 来访问 div 元素,并使用一种名为 showText 的方法来检查并查看我们何时滚动到该 div 元素上方 100 像素或更小,我正在为此使用 scrollTop。

然后我使用componentDidMount添加一个滚动的窗口事件监听器,并调用我的showText方法。

我是新手,所以我确信这里有错误并且可能是错误的代码。但任何帮助表示赞赏!

import React, {Component} from 'react';

class SlideIn extends Component{

    state={
        showTexts: false,
    }

    showText=()=>{
        const node= this.showTextRef;
        if(node.scollTop<=100)
        this.setState({
            showTexts: true
        })
    }



    componentDidMount(){
        window.addEventListener('scroll', this.showText() )
    }



    render(){
        const intro= document.querySelector('.intro')
        return(
            <div classname={this.state.showTexts ? 'showText' : 'hidden'} ref={node =>this.showTextRef = node}>
             {window.addEventListener('scroll', this.showText)}


                <h1>You did it!</h1> 
            </div>
        )
    }
}

export default SlideIn

我曾尝试在我的窗口滚动事件中使用 this.showText,正如您在 this.showText() 上方看到的,两者都没有奏效。我试图在我的 showText 方法中使用我的 div ref 上的 current 属性,它抛出了一个错误,说 scrollTop 无法定义 null 的属性。

我还是新手,从来没有以这种方式添加窗口事件侦听器,也从未使用过 scrollTop。

感谢您的帮助!

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    当您附加事件侦听器时,您必须将函数作为参数传递。添加事件侦听器时直接调用该函数。

    本质上,你需要改变:

    componentDidMount(){
        window.addEventListener('scroll', this.showText() )
    }
    

    到:

    componentDidMount(){
        window.addEventListener('scroll', this.showText)
    }
    

    在您的滚动监听器中,您应该检查window(这是您执行滚动的元素)的滚动位置:

    showText = () => {
        if (window.scrollY <= 100) {
            this.setState({
                showTexts: true
            });
        }    
    }
    

    另外,您正在render 方法中附加事件侦听器。 render 方法应该只包含渲染元素的逻辑。

    【讨论】:

    • 嘿@mgarcia 我确实尝试过,但没有运气:/
    • 我更新了响应以更正原始代码中的其他点。
    • 这是正确的,但我在我的 showText 方法中做了const top = window.pageYOffset;,并且做了if(top&gt;100){ 我遇到的主要问题是我在 body 和 html 上使用 CSS for overflow-x:hidden 和导致我的滚动事件侦听器出现问题。因此,我将整个主要 App 组件包装在一个 div 中,并在其上使用了 overflow-x:hidden,并且保持 body 和 html 不变,并且滚动事件有效。在此之前它是行不通的。
    【解决方案2】:

    将函数作为参数传递

    window.addEventListener('scroll', this.showText)
    

    并将其从返回中删除。

    那么你只需要在函数中做这个

    if(window.scrollY<=100)
        this.setState({
            showTexts: true
        })
    

    在此处使用您的 div 位置

    【讨论】:

      【解决方案3】:

      您需要使用 getBoundingCLientRect() 来获取滚动位置。 window.addEventListener("scroll", this.showText); 你需要传递 this.showText 而不是调用它。 类名有拼写错误。

      showText = () => {
          const node = this.showTextRef;
          const {
              y = 0
          } = (node && node.getBoundingClientRect()) || {};
      
          this.setState({
              showTexts: y <= 100
          });
      };
      
      componentDidMount() {
          window.addEventListener("scroll", this.showText);
      }
      
      render() {
          const intro = document.querySelector(".intro");
          return (
             <div
                className={this.state.showTexts ? "showText" : "hidden"}
                ref={node => (this.showTextRef = node)}
             >
                <h1>You did it!</h1>
             </div>
         );
      }
      

      工作示例的 condesandbox:https://codesandbox.io/s/intelligent-shannon-1p6sp

      【讨论】:

        【解决方案4】:

        我整理了一个工作示例供您参考,这是链接:https://codesandbox.io/embed/summer-forest-cksfh

        在您的代码中有几件事需要指出:

        componentDidMount(){
                window.addEventListener('scroll', this.showText() )
            }
        

        就像mgracia 提到的那样,使用this.showText() 意味着您直接调用该函数。正确的方法就是使用this.showText

        showText 函数中,你必须知道用户从文档顶部滚动了多远。因为它被称为使用:

        const top = window.pageYOffset || document.documentElement.scrollTop;
        

        现在可以安全地检查您的逻辑并根据您想要的值设置状态,这里我是这样说的:

        this.setState({
          showTexts: top <= 100
        })
        

        在您的componentDidMount中,您必须调用showText一次才能触发第一次页面加载,否则当您重新加载页面时不会触发该功能。

        希望有帮助

        完整代码:

        class SlideIn extends Component {
          state = {
            showTexts: false,
          }
        
          showText = () => {
            // get how many px we've scrolled
            const top = window.pageYOffset || document.documentElement.scrollTop;
            this.setState({
              showTexts: top <= 100
            })
          }
        
          componentDidMount() {
            window.addEventListener('scroll', this.showText)
            this.showText();
          }
        
          render() {
            return (
              <div className={`box ${this.state.showTexts ? 'visible' : 'hidden'}`}
                ref={node => this.showTextRef = node}>
              
                <h1>You did it!</h1>
              </div>
            )
          }
        }
        .App {
          font-family: sans-serif;
          text-align: center;
          height: 2500px;
        }
        
        .box {
          width: 100px;
          height: 100px;
          background: blue;
          position: fixed;
          left: 10px;
          top: 10px;
          z-index: 10;
        }
        
        .visible {
          display: block;
        }
        
        .hidden {
          display: none;
        }

        【讨论】:

          猜你喜欢
          • 2017-07-10
          • 1970-01-01
          • 2022-08-19
          • 2017-10-27
          • 2021-10-16
          • 2015-10-17
          • 2021-05-20
          • 2021-05-10
          • 2014-09-16
          相关资源
          最近更新 更多