본문 바로가기

cbp 프로젝트 진행

[2022.07.20] 최종 정리- 해당 영역 스크롤시 왼쪽 메뉴 글씨 색 변경 설정(2)

[2022.07.18] 해당 영역 스크롤시 왼쪽 메뉴 글씨 색 변경 설정(1)에 이어서 수정된 부분

 

1안 : 스크롤position을 숫자로 넣음

오류: 이렇게 설정시 콘텐츠가 추가되거나 반응형때 스크롤위치가 변경되면 오류가 생길 수 있음

import React from 'react';
import {useState, useEffect} from 'react';
import ztHistoryDt from './../../db/historyList.json';
import './../../styles/zeta/zetaHistory.scss';
import AOS from 'aos';
import 'aos/dist/aos.css'; 

const ZetaHistory = () => {
  const [ztHisDt,setZtHisDt]=useState([]);

  useEffect(()=>{
    setZtHisDt(ztHistoryDt);
    AOS.init();
  },[])

  const [scrollPosition, setScrollPosition] = useState(0);
  const updateScroll = () => {
    setScrollPosition(window.scrollY || document.documentElement.scrollTop);
  }
  useEffect(()=>{
    window.addEventListener('scroll', updateScroll);
    return () => {
      window.removeEventListener('scroll', updateScroll);
    };
  },[]);

  const refs = React.useRef([]);
  const handleClick = (i) => {
    refs.current[i].scrollIntoView({ behavior: 'smooth' });
  };
  
  const ztHisLists=[
    {
      'title':'first-tab',
      'subTitle':'2018 - 현재'
    },
    {
      'title':'second-tab',
      'subTitle':'2015 - 2017'
    },
    {
      'title':'third-tab',
      'subTitle':'2011 - 2014'
    },
    {
      'title':'fourth-tab',
      'subTitle':'2006 - 2010'
    }
  ];
 
  return (
    <div className='ztHisBox'>
      <div className="ztInner" >
        <h2 className='ztTitle'>
          연혁
        </h2>
        <div className='ztHisContent'>
          <ul className="ztHisTitle" data-aos="fade-up"  data-aos-duration="2500">
            <li className='ztHisTitleOr' data-aos="fade-up"  data-aos-duration="2000">제타플랜의 시작으로<br/> 한국 기업 컨설팅의</li>
            <li onClick={() => handleClick(0)}  className={0<=scrollPosition&&scrollPosition<=3393 ? 'ztHisTitleLiOn':'ztHisTitleLi'}>미래를 시작하다.</li>
            <li onClick={() => handleClick(1)}
              className={3393<scrollPosition&&scrollPosition<=6500 ?  'ztHisTitleLiOn':'ztHisTitleLi'}>뿌리를 통해 성장하다.</li>
            <li onClick={() => handleClick(2)}  className={6500<scrollPosition&&scrollPosition<=9600 ?  'ztHisTitleLiOn':'ztHisTitleLi'}>무한발전을 하다.</li>
            <li onClick={() => handleClick(3)}  className={9600<scrollPosition&&scrollPosition?  'ztHisTitleLiOn':'ztHisTitleLi'}>기반을 다지다.</li>
          </ul>
          <div className="ztHisTxtBox" data-aos="fade-up"  data-aos-duration="3000">
            <div className='ztHisTxt'>
              {
                ztHisLists.map(function(titleDt,i){
                  return(
                    <div className='ztHisTxtsBoxs' key={titleDt.title}  ref={(ref) => (refs.current[i] = ref)}>
                      <div className='ztHisTxtCotain'>
                        <p className='ztHisTxtsTitle' >
                          {titleDt.subTitle}
                        </p>
                        <div className='ztHisTxtsTotal'>
                          {
                            ztHisDt[ztHisLists[i].title]&&ztHisDt[ztHisLists[i].title].map(function(data,i){
                              return(
                                <div className='ztHisTexts' key={data.id}>
                                  <p className='ztHisTxtYear'>
                                    {data.year}
                                  </p>
                                  <div className='ztHisListsTxt'>
                                    {
                                      data.list.map(function(datas,i){
                                        return(
                                          <p className='ztHisListTxt' key={datas}>{datas}</p>
                                        )
                                      })
                                    }
                                  </div>
                                </div>
                              )
                            })
                          }
                        </div>
                      </div>
                    </div>
                  )
                })
              }
            </div>  
          </div>
        </div>
      </div>
    </div>
  );
};

export default ZetaHistory;

 

참고사이트:

 

 

 

 2안 

(1안 해결: window.pageYOffset + ele.getBoundingClientRect().top 을 이용하여 해당 영역의 scroll top기준을 구함)

오류: 이렇게 설정시 처음 1의 글자에 on이 안들어오고 ,조금 내리면 on이 붙음(스크롤되는 영역)

import React from 'react';
import {useState, useEffect,useRef} from 'react';
import ztHistoryDt from './../../db/historyList.json';
import './../../styles/zeta/zetaHistory.scss';
import AOS from 'aos';
import 'aos/dist/aos.css'; 

const ZetaHistory = () => {
  const [ztHisDt,setZtHisDt]=useState([]);
  const refs = useRef([]);
  const titleRefs= useRef([]);
  /*   const titleRefs0 = useRef();
  const titleRefs1 = useRef();
  const titleRefs2 = useRef();
  const titleRefs3 = useRef(); */
  useEffect(()=>{
    setZtHisDt(ztHistoryDt);
    AOS.init();
  },[])

  const [scrollPosition, setScrollPosition] = useState(0);
  const updateScroll = () => {
    setScrollPosition(window.scrollY || document.documentElement.scrollTop); 
    refs.current.forEach((ele,idx)=> {
      let valueTop =  parseInt(window.pageYOffset + ele.getBoundingClientRect().top ) ; 
      let valueBottom = parseInt( window.pageYOffset + ele.getBoundingClientRect().bottom); 
      let titleRefName = titleRefs.current[idx]
      titleRefName.className=valueTop<=scrollPosition&&scrollPosition<=valueBottom ? 'ztHisTitleLiOn':'ztHisTitleLi' ;
    }) 
    
  }

  useEffect(()=>{
    window.addEventListener('scroll', updateScroll);
    return () => {
      window.removeEventListener('scroll', updateScroll);
    };
  },[scrollPosition]);



  const handleClick = (i) => {
    refs.current[i].scrollIntoView({ behavior: 'smooth' });
  };
  
  /* ref={(ref) => (refs.current[i] = ref) */
  
  const ztHisLists=[
    {
      'title':'first-tab', 
      'subTitle':'2018 - 현재'
    },
    {
      'title':'second-tab',
      'subTitle':'2015 - 2017'
    },
    {
      'title':'third-tab',
      'subTitle':'2011 - 2014'
    },
    {
      'title':'fourth-tab',
      'subTitle':'2006 - 2010'
    }
  ];

 
 
  return (
    <div className='ztHisBox'>
      <div className="ztInner" >
        <h2 className='ztTitle'>
          연혁
        </h2>
        <div className='ztHisContent'>
          <ul className="ztHisTitle" data-aos="fade-up"  data-aos-duration="2500">
            <li className='ztHisTitleOr' data-aos="fade-up"  data-aos-duration="2000">제타플랜의 시작으로<br/> 한국 기업 컨설팅의</li>
            <li onClick={() => handleClick(0)} ref={(ref)=>(titleRefs.current[0] = ref)} className='ztHisTitleLiOn'>미래를 시작하다.</li>
            <li onClick={() => handleClick(1)} ref={(ref)=>(titleRefs.current[1] = ref)} className='ztHisTitleLi'>뿌리를 통해 성장하다.</li>
            <li onClick={() => handleClick(2)} ref={(ref)=>(titleRefs.current[2] = ref)} className='ztHisTitleLi'>무한발전을 하다</li>
            <li onClick={() => handleClick(3)} ref={(ref)=>(titleRefs.current[3] = ref)}  className='ztHisTitleLi'>기반을 다지다</li>
            {/*  <li onClick={() => handleClick(0)}  className={0<=scrollPosition&&scrollPosition<=valueBottom ? 'ztHisTitleLiOn':'ztHisTitleLi'}>미래를 시작하다.</li>
            <li onClick={() => handleClick(1)}
              className={valueTop<scrollPosition&&scrollPosition<=valueBottom ?  'ztHisTitleLiOn':'ztHisTitleLi'}>뿌리를 통해 성장하다.</li>
            <li onClick={() => handleClick(2)}  className={valueTop<scrollPosition&&scrollPosition<=valueBottom ?  'ztHisTitleLiOn':'ztHisTitleLi'}>무한발전을 하다.</li>
            <li onClick={() => handleClick(3)}  className={valueBottom<scrollPosition&&scrollPosition?  'ztHisTitleLiOn':'ztHisTitleLi'}>기반을 다지다.</li> */}
          </ul>
          <div className="ztHisTxtBox" data-aos="fade-up"  data-aos-duration="3000">
            <div className='ztHisTxt'>
              {
                ztHisLists.map(function(titleDt,i){
                  return(
                    <div className='ztHisTxtsBoxs' key={titleDt.title}  ref={(ref) => (refs.current[i] = ref)}>
                      <div className='ztHisTxtCotain'>
                        <p className='ztHisTxtsTitle' >
                          {titleDt.subTitle}
                        </p>
                        <div className='ztHisTxtsTotal'>
                          {
                            ztHisDt[ztHisLists[i].title]&&ztHisDt[ztHisLists[i].title].map(function(data,i){
                              return(
                                <div className='ztHisTexts' key={data.id}>
                                  <p className='ztHisTxtYear'>
                                    {data.year}
                                  </p>
                                  <div className='ztHisListsTxt'>
                                    {
                                      data.list.map(function(datas,i){
                                        return(
                                          <p className='ztHisListTxt' key={datas}>{datas}</p>
                                        )
                                      })
                                    }
                                  </div>
                                </div>
                              )
                            })
                          }
                        </div>
                      </div>
                    </div>
                  )
                })
              }
            </div>  
          </div>
        </div>
      </div>
    </div>
  );
};

export default ZetaHistory;

 

 3안 (if 조건문을 사용하여 0일때는 따로 범위를 설정하여 2안 오류해결)

오류: 클릭시 올라가는 범위보다 스크롤top범위가 위에 있어서 클릭시 on이 스크롤top까지 내려야 먹힘

import React from 'react';
import {useState, useEffect,useRef} from 'react';
import ztHistoryDt from './../../db/historyList.json';
import './../../styles/zeta/zetaHistory.scss';
import AOS from 'aos';
import 'aos/dist/aos.css'; 

const ZetaHistory = () => {
  const [ztHisDt,setZtHisDt]=useState([]);
  const refs = useRef([]);
  const titleRefs= useRef([]);
  useEffect(()=>{
    setZtHisDt(ztHistoryDt);
    AOS.init();
  },[])

  const [scrollPosition, setScrollPosition] = useState(0);
  const updateScroll = () => {
    setScrollPosition(window.scrollY || document.documentElement.scrollTop); 
    refs.current.forEach((ele,idx)=> {
      let valueTop =  parseInt(window.pageYOffset + ele.getBoundingClientRect().top ) ; 
      let valueBottom = parseInt( window.pageYOffset + ele.getBoundingClientRect().bottom); 
      let titleRefName = titleRefs.current[idx]
      if(idx===0){
        titleRefName.className=0<=scrollPosition&&scrollPosition<=valueBottom ? 'ztHisTitleLiOn':'ztHisTitleLi' ;
      }else{
        titleRefName.className=valueTop<=scrollPosition&&scrollPosition<=valueBottom ? 'ztHisTitleLiOn':'ztHisTitleLi' ;
      }
       
    }) 
    
  }

  useEffect(()=>{
    window.addEventListener('scroll', updateScroll);
    return () => {
      window.removeEventListener('scroll', updateScroll);
    };
  },[scrollPosition]);

  const handleClick = (i) => {
    refs.current[i].scrollIntoView({ behavior: 'smooth' });
  };
    
  const ztHisLists=[
    {
      'title':'first-tab', 
      'subTitle':'2018 - 현재'
    },
    {
      'title':'second-tab',
      'subTitle':'2015 - 2017'
    },
    {
      'title':'third-tab',
      'subTitle':'2011 - 2014'
    },
    {
      'title':'fourth-tab',
      'subTitle':'2006 - 2010'
    }
  ];

  return (
    <div className='ztHisBox'>
      <div className="ztInner" >
        <h2 className='ztTitle'>
          연혁
        </h2>
        <div className='ztHisContent'>
          <ul className="ztHisTitle" data-aos="fade-up"  data-aos-duration="2500">
            <li className='ztHisTitleOr' data-aos="fade-up"  data-aos-duration="2000">제타플랜의 시작으로<br/> 한국 기업 컨설팅의</li>
            <li onClick={() => handleClick(0)} ref={(ref)=>(titleRefs.current[0] = ref)} className='ztHisTitleLiOn'>미래를 시작하다.</li>
            <li onClick={() => handleClick(1)} ref={(ref)=>(titleRefs.current[1] = ref)} className='ztHisTitleLi'>뿌리를 통해 성장하다.</li>
            <li onClick={() => handleClick(2)} ref={(ref)=>(titleRefs.current[2] = ref)} className='ztHisTitleLi'>무한발전을 하다</li>
            <li onClick={() => handleClick(3)} ref={(ref)=>(titleRefs.current[3] = ref)}  className='ztHisTitleLi'>기반을 다지다</li>
          </ul>
          <div className="ztHisTxtBox" data-aos="fade-up"  data-aos-duration="3000">
            <div className='ztHisTxt'>
              {
                ztHisLists.map(function(titleDt,i){
                  return(
                    <div className='ztHisTxtsBoxs' key={titleDt.title}  ref={(ref) => (refs.current[i] = ref)}>
                      <div className='ztHisTxtCotain'>
                        <p className='ztHisTxtsTitle' >
                          {titleDt.subTitle}
                        </p>
                        <div className='ztHisTxtsTotal'>
                          {
                            ztHisDt[ztHisLists[i].title]&&ztHisDt[ztHisLists[i].title].map(function(data,i){
                              return(
                                <div className='ztHisTexts' key={data.id}>
                                  <p className='ztHisTxtYear'>
                                    {data.year}
                                  </p>
                                  <div className='ztHisListsTxt'>
                                    {
                                      data.list.map(function(datas,i){
                                        return(
                                          <p className='ztHisListTxt' key={datas}>{datas}</p>
                                        )
                                      })
                                    }
                                  </div>
                                </div>
                              )
                            })
                          }
                        </div>
                      </div>
                    </div>
                  )
                })
              }
            </div>  
          </div>
        </div>
      </div>
    </div>
  );
};

export default ZetaHistory;

 

 4안 최종 : 조건문에서 스크롤되는 범위를 일정스크롤수 제외하여 설정함

if(idx===0){
 titleRefName.className=0<=scrollPosition&&scrollPosition<valueBottom-100 ? 'ztHisTitleLiOn':'ztHisTitleLi' ;
}else{
 titleRefName.className=valueTop<scrollPosition+100&&scrollPosition<valueBottom-100 ? 'ztHisTitleLiOn':'ztHisTitleLi' ;
};

 

▼ 전체코드 (4안)

import React from 'react';
import {useState, useEffect,useRef} from 'react';
import ztHistoryDt from './../../db/historyList.json';
import './../../styles/zeta/zetaHistory.scss';
import AOS from 'aos';
import 'aos/dist/aos.css'; 

const ZetaHistory = () => {
  const [ztHisDt,setZtHisDt]=useState([]);
  const refs = useRef([]);
  const titleRefs= useRef([]);
  useEffect(()=>{
    setZtHisDt(ztHistoryDt);
    AOS.init();
  },[]);

  const [scrollPosition, setScrollPosition] = useState(0);
  const updateScroll = () => {
    setScrollPosition(window.scrollY || document.documentElement.scrollTop);
    refs.current.forEach((ele,idx)=> {
      let valueTop =  parseInt(window.pageYOffset + ele.getBoundingClientRect().top ) ; 
      let valueBottom = parseInt( window.pageYOffset + ele.getBoundingClientRect().bottom); 
      let titleRefName = titleRefs.current[idx]
      if(idx===0){
        titleRefName.className=0<=scrollPosition&&scrollPosition<valueBottom-100 ? 'ztHisTitleLiOn':'ztHisTitleLi' ;
      }else{
        titleRefName.className=valueTop<scrollPosition+100&&scrollPosition<valueBottom-100 ? 'ztHisTitleLiOn':'ztHisTitleLi' ;
      };
    });
  };

  useEffect(()=>{
    window.addEventListener('scroll', updateScroll);
    return () => {
      window.removeEventListener('scroll', updateScroll);
    };
  },[scrollPosition]);

  const handleClick = (i) => {
    refs.current[i].scrollIntoView({ behavior: 'smooth'});
  };
    
  const ztHisLists=[
    {
      'title':'first-tab', 
      'subTitle':'2018 - 현재'
    },
    {
      'title':'second-tab',
      'subTitle':'2015 - 2017'
    },
    {
      'title':'third-tab',
      'subTitle':'2011 - 2014'
    },
    {
      'title':'fourth-tab',
      'subTitle':'2006 - 2010'
    }
  ];

  return (
    <div className='ztHisBox'>
      <div className="ztInner" >
        <h2 className='ztTitle'>
          연혁
        </h2>
        <div className='ztHisContent'>
          <ul className="ztHisTitle" >
            <li className='ztHisTitleOr'>제타플랜의 시작으로<br/> 한국 기업 컨설팅의</li>
            <li onClick={() => handleClick(0)} ref={(ref)=>(titleRefs.current[0] = ref)} className='ztHisTitleLiOn'>미래를 시작하다.</li>
            <li onClick={() => handleClick(1)} ref={(ref)=>(titleRefs.current[1] = ref)} className='ztHisTitleLi'>뿌리를 통해 성장하다.</li>
            <li onClick={() => handleClick(2)} ref={(ref)=>(titleRefs.current[2] = ref)} className='ztHisTitleLi'>무한발전을 하다</li>
            <li onClick={() => handleClick(3)} ref={(ref)=>(titleRefs.current[3] = ref)}  className='ztHisTitleLi'>기반을 다지다</li>
          </ul>
          <div className="ztHisTxtBox" data-aos="fade-up"  data-aos-duration="3000">
            <div className='ztHisTxt'>
              {
                ztHisLists.map(function(titleDt,i){
                  return(
                    <div className='ztHisTxtsBoxs' key={titleDt.title}  ref={(ref) => (refs.current[i] = ref)}>
                      <div className='ztHisTxtCotain'>
                        <p className='ztHisTxtsTitle' >
                          {titleDt.subTitle}
                        </p>
                        <div className='ztHisTxtsTotal'>
                          {
                            ztHisDt[ztHisLists[i].title]&&ztHisDt[ztHisLists[i].title].map(function(data,i){
                              return(
                                <div className='ztHisTexts' key={data.id}>
                                  <p className='ztHisTxtYear'>
                                    {data.year}
                                  </p>
                                  <div className='ztHisListsTxt'>
                                    {
                                      data.list.map(function(datas,i){
                                        return(
                                          <p className='ztHisListTxt' key={datas}>{datas}</p>
                                        )
                                      })
                                    }
                                  </div>
                                </div>
                              )
                            })
                          }
                        </div>
                      </div>
                    </div>
                  )
                })
              }
            </div>  
          </div>
        </div>
      </div>
    </div>
  );
};

export default ZetaHistory;