Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在滚动时响应更改图像源事件_Javascript_Css_Reactjs - Fatal编程技术网

Javascript 在滚动时响应更改图像源事件

Javascript 在滚动时响应更改图像源事件,javascript,css,reactjs,Javascript,Css,Reactjs,作为一个新加入React但熟悉JavaScript的人,我在知道在给定React组件中确切地放置某些功能时遇到了一些问题,并且不确定我遇到的这个问题是我的React逻辑问题还是加载图像时的延迟时间问题,虽然如果是后者,我不理解这一点,因为我将图像预加载到一个隐藏的div中 我的预期工作流程如下所示: componentDidMount() { if (this.props.changeColorOnScroll) { window.addEventListener("scro

作为一个新加入React但熟悉JavaScript的人,我在知道在给定React组件中确切地放置某些功能时遇到了一些问题,并且不确定我遇到的这个问题是我的React逻辑问题还是加载图像时的延迟时间问题,虽然如果是后者,我不理解这一点,因为我将图像预加载到一个隐藏的div中

我的预期工作流程如下所示:

componentDidMount() {
    if (this.props.changeColorOnScroll) {
      window.addEventListener("scroll", this.headerColorChange);
    }
  }
  headerColorChange() {
    console.log("Scroll Fire!");
    const { classes, color, changeColorOnScroll} = this.props;
    const windowsScrollTop = window.pageYOffset;
    if (windowsScrollTop > changeColorOnScroll.height) {
      document.body
        .getElementsByTagName("header")[0]
        .classList.remove(classes[color]);
      document.body
        .getElementsByTagName("header")[0]
        .classList.add(classes[changeColorOnScroll.color]);
     document
        .getElementById("headerLogoContainer").getElementsByClassName("logo")[0]
        .classList.add('hide');
     document
        .getElementById("headerLogoContainer").getElementsByClassName("logoalt")[0]
        .classList.remove('hide');
    } else {
      document.body
        .getElementsByTagName("header")[0]
        .classList.add(classes[color]);
      document.body
        .getElementsByTagName("header")[0]
        .classList.remove(classes[changeColorOnScroll.color]);
     document
        .getElementById("headerLogoContainer").getElementsByClassName("logo")[0]
        .classList.remove('hide');
     document
        .getElementById("headerLogoContainer").getElementsByClassName("logoalt")[0]
        .classList.add('hide');
    }
  } 
  • 加载两个图像,其中一个“预加载”,高度为0,作为
    hide
    类的一部分
  • 当窗口滚动时,有效地在这两个图像中的任何一个上切换
    隐藏
    类,以便根据滚动位置有效地更改显示的图像。发生这种情况时,标题的背景色也将改变
  • 在我的组件
    Header.jsx中,我有以下内容:

    componentDidMount() {
        if (this.props.changeColorOnScroll) {
          window.addEventListener("scroll", this.headerColorChange);
        }
      }
      headerColorChange() {
        console.log("Scroll Fire!");
        const { classes, color, changeColorOnScroll} = this.props;
        const windowsScrollTop = window.pageYOffset;
        if (windowsScrollTop > changeColorOnScroll.height) {
          document.body
            .getElementsByTagName("header")[0]
            .classList.remove(classes[color]);
          document.body
            .getElementsByTagName("header")[0]
            .classList.add(classes[changeColorOnScroll.color]);
         document
            .getElementById("headerLogoContainer").getElementsByClassName("logo")[0]
            .classList.add('hide');
         document
            .getElementById("headerLogoContainer").getElementsByClassName("logoalt")[0]
            .classList.remove('hide');
        } else {
          document.body
            .getElementsByTagName("header")[0]
            .classList.add(classes[color]);
          document.body
            .getElementsByTagName("header")[0]
            .classList.remove(classes[changeColorOnScroll.color]);
         document
            .getElementById("headerLogoContainer").getElementsByClassName("logo")[0]
            .classList.remove('hide');
         document
            .getElementById("headerLogoContainer").getElementsByClassName("logoalt")[0]
            .classList.add('hide');
        }
      } 
    
    我相信这是在
    componentDidMount()
    中附加事件侦听器的正确位置。我的问题是,当我滚动时,窗口会随着图像的更改而冻结,即使我在此处预加载了图像:

    render() {
        const {
          classes,
          color,
          rightLinks,
          leftLinks,
          brand,
          logo,
          logoalt,
          fixed,
          absolute
        } = this.props;
        const appBarClasses = classNames({
          [classes.appBar]: true,
          [classes[color]]: color,
          [classes.absolute]: absolute,
          [classes.fixed]: fixed
        });
        let brandComponent;
        if(!logo){
        brandComponent = (
          <Button className={classes.title}>
            {brand}
          </Button>
        );
        }else{
        brandComponent = (
          <div id='headerLogoContainer'>
          <img className='logo'  src={logo}></img>
          <img className='logoalt hide'  src={logoalt}></img>
          </div>
        );
        }
        return (
          <AppBar className={appBarClasses}>
            <Toolbar className={classes.container}>
              {leftLinks !== undefined ? brandComponent : null}
              <div className={classes.flex}>
                {leftLinks !== undefined ? (
                  <Hidden smDown implementation="css">
                    {leftLinks}
                  </Hidden>
                ) : (
                  brandComponent
                )}
              </div>
    
    然后在我的渲染中

    render() {
        const {
          classes,
          color,
          rightLinks,
          leftLinks,
          brand,
          logo,
          logoalt,
          fixed,
          absolute
        } = this.props;
        const{
            mobileOpen,
            logoaltState
        } = this.state
        const appBarClasses = classNames({
          [classes.appBar]: true,
          [classes[color]]: color,
          [classes.absolute]: absolute,
          [classes.fixed]: fixed
        });
        let brandComponent;
        if(!logo){
        brandComponent = (
          <Button className={classes.title}>
            {brand}
          </Button>
        );
        }else{
        brandComponent = (
          <div id='headerLogoContainer'>
          <img className='logo'  src={logo} style={{display: logoaltState === false ? "block" : "none"}}></img>
          <img className='logoalt'   src={logoalt} style={{display: logoaltState === true ? "block" : "none"}}></img>
          </div>
        );
        }
    
    render(){
    常数{
    班级,
    颜色
    右链接,
    左链接,
    品牌,
    标志
    logoalt,
    固定的,
    绝对的
    }=这是道具;
    常数{
    移动电话,
    logoaltState
    }=这个州
    const appBarClasses=类名({
    [classes.appBar]:正确,
    [类别[颜色]]:颜色,
    [类别.绝对]:绝对,
    [类别.固定]:固定
    });
    让brandComponent;
    如果(!徽标){
    品牌成分=(
    {brand}
    );
    }否则{
    品牌成分=(
    );
    }
    
    不同的代码/方法,相同的问题

    编辑2:

    我不认为这是应用程序逻辑的问题,因为正如我所提到的,它只是在图像/状态第一次需要更改时冻结。我认为这是某种首次加载问题,即使我没有任何网络请求,可能我包括了错误的图像源?或者在React图像中需要预加载通过其他一些方法,因为图像源在包含时稍微关闭…即
    /static/media/logo.ad924167.png
    而不是
    require(“assets/img/tovlogo.png”
    我认为这是因为我的节点服务器设置,但我还是不太清楚到底发生了什么,因为我对这个生态系统相当陌生……我使用的是,这就是这个组件的来源

    主题文件本身是这样的:所以我想知道它是如何处理图像的,考虑到实际的
    src
    require
    的性质不同……但是,同样没有对图像的额外请求……这只是CSS/样式的改变

    编辑3:

    这就是我的调试器(Chrome:Performance)冻结时的样子:

    我意识到在绘制时图像相当大,但不应该预加载地址…我想不是因为这是一个网络预加载,而不是带有
    display:none的绘制预加载;“
    …也许我可以尝试使用
    不透明度
    CSS属性,但这会使其他CSS复杂化…通常有更好的方法吗?”

    最终编辑:


    我的图像超过10000像素宽…我用它作为徽标,所以直到我做了性能指标后才意识到它有多糟糕…我猜这就是它冻结的原因…抱歉(

    与其手动更改DOM元素的类,不如利用组件状态,根据滚动位置在活动图像之间切换,这样会更容易

    示例

    类应用程序扩展了React.Component{
    状态={active:0};
    componentDidMount(){
    window.addEventListener(“滚动”,this.handleScroll);
    }
    组件将卸载(){
    window.removeEventListener(“滚动”,this.handleScroll);
    }
    handleScroll=事件=>{
    常量{pageYOffset}=window;
    const{active}=this.state;
    如果(页面偏移量>=500&&active==0){
    this.setState({active:1});
    }else if(页面偏移<500&&active==1){
    this.setState({active:0});
    }
    };
    render(){
    const{active}=this.state;
    返回(
    );
    }
    }
    ReactDOM.render(,document.getElementById(“根”);
    
    
    你能解释或链接到一个概念性的解释吗?这是简单的反应方式吗?我不明白为什么当事件侦听器中的
    if
    条件启动时,直接访问DOM会失败。@SummerDeveloper是的,我没有比声明式呈现更好的解释了,也就是说,你应该尝试从状态和道具派生你的用户界面。当然,有一些方法是强制性的,但这是比较少见的。我不确定你问题中的代码为什么也不起作用。老实说,我不太明白。所以我是这样做的,反应方式,当图像发生变化时,我仍然会感到尴尬的延迟/冻结…有些时候还有其他事情在这里发生……有什么想法吗?因为我的图像是一幅巨大的图像,超过10000像素宽,我没有意识到……感谢关于州的指示,并对浪费的时间表示抱歉。:)