【问题标题】:How to dynamically render an element after scrolling to a certain position in a page?滚动到页面中的某个位置后如何动态渲染元素?
【发布时间】:2020-04-18 09:32:35
【问题描述】:

我希望我的“emailForm”组件在用户滚动到“洗衣区”的开头后呈现在我的导航栏上,有人知道该怎么做吗?

我试过{window.scrollY > 500px ? EmailForm : "" } 但它不起作用,我对 react 还不是很熟悉,所以也许你能帮我找出正确的方法来实现它?

容器:

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

import React, {Component} from 'react';


// Components
import Section from '../components/styledComponents/section';
import EmailForm from "../components/emailForm"
import Navbar from './containers/navbar';

export default class Individuals extends Component {


	render() {
		const { iconStyle } = this;
		return (
      <NavBar/>
			<main className="individuals">
				{/*Header section*/}
				<Section height="100vh" usedScreen="84px" className="your-laundromat-connected">
							<div className="title">
								<h1>
									Title</span>.
								</h1>
							</div>
						</div>
						<div className="subscribe-container">
						<div className="catchphrase-input">Prévenez-moi :</div>
						<EmailForm/>
						</div>
					</div>
				</Section>

				{/*Laundry section*/}
				<div className="container-laverie">
				<h2>Votre temps est précieux. Utilisez-le autrement.</h2>
                <p>Finie l'attente interminable à la laverie... grâce à l'application Lavigo vous reprenez le contrôle sur votre emploi du temps.</p>
					{/* </div>	 */}
				</div>
			</main>

		);
	}
}

导航栏组件:

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

import React from 'react';
import INavbarState from '../containers/interfaces/Inavbar';
//Librairies
import $ from 'jquery'
import EmailForm from '../components/emailForm'


export default class Individuals extends React.PureComponent<{}, INavbarState | any> {
	constructor(props: INavbarState | any) {
		super(props);
		this.state = {
		  showMenu: false,
		  scrollTop: true
		};
	}

	componentDidMount() {
		const that = this;
		let $win = $(window);
	
		$win.scroll(function () {
		  if ($win.scrollTop() == 0) {
			if (!that.state.scrollTop) {
			  that.setState({ scrollTop: true })
			}
		  } else {
			if (that.state.scrollTop) {
			  that.setState({ scrollTop: false })
			}
		  }
		});

		if(window.innerWidth <= 1024)
		{
		  that.setState({showMenu:false})
			// hide menubar
		}else{
		  that.setState({showMenu:true})
		   // show menubar
		}

	  window.onresize = function(event:any) {
		if(window.innerWidth <= 1024)
		{
		  that.setState({showMenu:false})
			// hide menubar
		}else{
		  that.setState({showMenu:true})
		   // show menubar
		}

	   if (window.scrollY > 1000) {

	   }  
	  };



	  ontoggle = () => {
		if(window.innerWidth <= 1024)
		  {
			this.setState({ showMenu: !this.state.showMenu })
			  // hide menubar
		  }else{
			this.setState({showMenu:true})
			 // show menubar
		  }
	  }
	}

	render() {
	return (
		<nav className="nav">
			<div className="d-flex align-items-center">
				<div className="container-email">
				<EmailForm/> 
				</div>
			</div>
		</nav>
	);
  };
}

【问题讨论】:

    标签: javascript reactjs scroll dom-events


    【解决方案1】:

    您好,请检查此 ScrollExample 和 ScrollChild 组件。我在 ScrollExample 组件中使用了 ScrollChild。当您向下滚动到 200 时,它将在屏幕上显示 ScrollChild 组件。

    ScrollExample 组件

    import * as React from "react";
    import ScrollChild from "./ScrollChild";
    
    export default class ScrollExample extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                isChildActive: false
            }
        }
    
        componentDidMount() {
            window.addEventListener('scroll', this.handleScroll);
        }
    
        componentWillUnmount() {
            window.removeEventListener('scroll', this.handleScroll);
        }
    
        handleScroll = (event) => {
            let scrollTop = window.scrollY;
    
            if (scrollTop > 200)
                this.setState({isChildActive: true});
            else
                this.setState({isChildActive: false});
        };
    
        render() {
            return (
                <div style={{height: 2000}}>
                    Scroll down to show the EmailForm
                    {
                        this.state.isChildActive ? <ScrollChild/> : null
                    }
                </div>
            );
        }
    }
    

    ScrollChild 组件

    import React, {useEffect, useState} from 'react';
    
    function ScrollChild(props) {
        return (
            <div style={{backgroundColor: '#1569C7', color: '#ffffff', width: 500, marginTop: 300, padding: 20}}>
                THIS IS A DUMMY TEXT
                <h1>How to dynamically render an element after scrolling to a certain position in a page?</h1>
    
                I would like my "emailForm" component to render on my Navbar after user scrolled to beginning of
                "laundry section", does someone know how to do that?
    
                I tried window.scrollY > 500px ? EmailForm : "" But it doesn't work, I am not very familiar yet with
                react so maybe you could help me figure out the right method to achieve it?
    
                I would like my "emailForm" component to render on my Navbar after user scrolled to beginning of
                "laundry section", does someone know how to do that?
    
                I tried window.scrollY > 500px ? EmailForm : "" But it doesn't work, I am not very familiar yet with
                react so maybe you could help me figure out the right method to achieve it?
    
                I would like my "emailForm" component to render on my Navbar after user scrolled to beginning of
                "laundry section", does someone know how to do that?
    
                I tried window.scrollY > 500px ? EmailForm : "" But it doesn't work, I am not very familiar yet with
                react so maybe you could help me figure out the right method to achieve it?
    
                I would like my "emailForm" component to render on my Navbar after user scrolled to beginning of
                "laundry section", does someone know how to do that?
    
                I tried window.scrollY > 500px ? EmailForm : "" But it doesn't work, I am not very familiar yet with
                react so maybe you could help me figure out the right method to achieve it?
            </div>
        );
    }
    
    export default ScrollChild;
    

    【讨论】:

      【解决方案2】:

      我现在没有示例代码,但您可以执行以下操作: 在滚动时,您可以检查元素是否可见(带有位置和滚动位置)。如果是的话,你可以做一个jQuery动画

      【讨论】:

        【解决方案3】:

        每次你的状态改变时,它都会调用你的组件的渲染。然而在你的渲染中,什么都不会改变,因为你的渲染不依赖于this.state.scrollTop

        要解决此问题,您需要做两件事: 1.当用户滚动超过阈值(500px)时更新状态 2. 在render() 方法中使用这个新的状态值,重新渲染组件。

        我创建了一个示例,当this.state.showEmailForm 更改时,我更改了表单的不透明度。你可以看到和下面的例子:

        class App extends React.Component {
          constructor(props) {
        super(props);
        this.state = {
          showEmailForm: false,
        };
          }
        
          componentDidMount = () => {
        window.addEventListener("scroll", this.onScroll);
          };
        
          componentWillUnmount = () => {
        window.removeEventListener("scroll", this.onScroll);
          };
        
          onScroll = () => {
        this.setState({
          showEmailForm: window.scrollY > 500,
        });
          };
        
          render() {
        return (
          <div className="app">
            <p>
              {" "}
              Lorem ipsum dolor sit amet, consectetur adipiscing elit.Sed aliquet
              iaculis tellus id faucibus.Sed pellentesque sit amet tortor a
              mattis.Nullam ligula ante, condimentum eget ipsum vitae, fringilla
              consequat lorem.Aliquam vitae enim sem.Morbi consequat quam vel
              faucibus blandit.Fusce tempus fringilla neque sit amet eleifend.Nullam
              enim augue, facilisis a vehicula id, malesuada ut sapien.Curabitur vel
              dui ut risus placerat eleifend.Maecenas pulvinar magna ante, a congue
              nibh laoreet id.In consectetur viverra ligula, a mattis dolor blandit
              id.Aliquam ante massa, sollicitudin eget augue id, malesuada fringilla
              sem.Sed viverra pretium dignissim.Morbi ut volutpat ante, sed
              tincidunt quam.Praesent placerat, ipsum commodo venenatis sodales,
              tellus ante pellentesque ante, ac ultrices massa velit et velit.{" "}
            </p>
            <form
              style={{
                opacity: this.state.showEmailForm ? 1 : 0,
              }}
            >
              <label>
                Name <br />
                <input type="text" />
              </label>
        
              <label>
                Email <br />
                <input type="email" />
              </label>
        
              <input type="submit" value="Submit" />
            </form>
          </div>
        );
          }
        }
        
        const rootElement = document.querySelector("#container");
        ReactDOM.render(<App />, rootElement);
        .app {
          height: 1000vh;
          background: palevioletred;
          padding: 1em;
          display: flex;
        }
        
        p {
          font-size: 2em;
          width: 50%;
        }
        
        input {
          display: block;
        }
        
        label {
          font-weight: bold;
        }
        
        form {
          padding: 1em;
          position: fixed;
          top: 1em;
          right: 1em;
          transition: opacity 0.5s;
        }
        <div id="container"></div>
        
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

        【讨论】:

          猜你喜欢
          • 2012-05-20
          • 2014-04-08
          • 2016-10-22
          • 2021-08-13
          • 1970-01-01
          • 2016-01-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多