본문 바로가기

cbp 프로젝트 진행

[2022.07.13] 특정 영역 도달 시 한 쪽은 스크롤, 다른 쪽은 고정 fix시키기 오류

import React from 'react';
import {useState, useEffect, useRef} from 'react';
import certiUrl from './../../db/certificateList.json';
import awardUrl from './../../db/awardList.json';
import './../../styles/zeta/index.scss';

const Index = () => {
  const [certiData,setCertiData]=useState([]);
  const [awardData,setAwardData]=useState([]);

  const [selectedTab, setSelectedTab] = useState(certiUrl);
  //console.log(certiData);

  
  
  useEffect(()=>{
    setCertiData(certiUrl);
    setAwardData(awardUrl);
  },[])

  /*  */
  const [scrollY, setScrollY] = useState(0);

  const handleScroll = () => {
    const scrollPosition = window.pageYOffset;
    setScrollY(scrollPosition)
  };

  useEffect( () => {
    window.addEventListener('scroll', handleScroll);

    return () => {
      window.removeEventListener('scroll', handleScroll)
    }
  }, []);

  console.log(scrollY)

  return (
    <div className='ztInfoBox'>
      <div className='ztIntro'>
        <h2 className='ztTitle'>
          회사소개
        </h2>
        <div className='ztInfoText'>
          <p className='ztTextTitle'>시작과 성장과 안정을 위한 컨설팅 솔루션 </p>
          <p className='ztTextWh'>체계적인 분석과 함께 정확한 대안을 가진 솔루션을 제공<br/>
            기업자금지원지원/기업구구조조정/기업전략컨설팅<br/>
            투자유치와 IPO, M&A 단계에 이를 수 있도록 지원<br/>
            한국 30여개 벤처캐피털과 해외 50여개 PEF 및 벤처캐피털 등과 제휴</p>
          <p className='ztTextGr'>
            안정을 원하는 모든 기업에게 위험을 제거한 최대의 기회만을 제공할 것을 약속드립니다.<br/>
            기업들의 꿈을 제타플랜이 함께 응원하겠습니다.<br/>
            체계적인 서비스로 성공과 안정된 기업으로 만들어 드리겠습니다.
          </p>
        </div>
      </div>

      <div className='ztMessage'>
        <div className='ztMessageInner'>
          <div className='ztMessageBox'>
            <img className='ztCircle' src={require('./../../img/zeta/zeta_circle.png')} alt="circle"/>
            <div className='ztCeoTexts'>
              <h2>CEO'S MESSAGE</h2>
              <p className='ztCeoText'>
                (주)제타플랜인베스트는  “지구상의 모든 기업들의 시작과 성장과 안정을 위한 컨설팅 솔루션 제공”이라는 대명제를 가지고 경영컨설팅 서비스를 제공하고 있습니다. 체계적인 컨설팅 서비스를 통해 기업의 시작과 성장, 안정을 원하는 모든 기업에게 위험을
                제거한 최대의 기회만을 제공할 것을 약속드립니다.
              </p>
              <p className='ztCeoName'>
                CEO/홍현권
              </p>
            </div>
          </div>
          
          <p className='ztCeoImg'>
            <img src={require('./../../img/zeta/zeta_hyunkyun@2x.png')} alt="zt_ceo" />
          </p>
        </div>
      </div>

      <div className='ztAwardsBox'>
        <div className='ztAwardsBoxInner'>
          <div className={ ( 1800 < scrollY ) ? 'ztAwardsTab fixed' : 'ztAwardsTab' } >
            <p onClick={() => setSelectedTab(certiData)} className={selectedTab===certiData?'ztCertificate active':'ztCertificate'}>인증서</p>
            <p onClick={() => setSelectedTab(awardData)} className={selectedTab===awardData?'ztAward active':'ztAward'}>상장</p>
          </div>
          {/* <div className='ztAwardsTitle'> */}
          <div className={ ( 1800 < scrollY ) ? 'ztAwardsTitle fixed' : 'ztAwardsTitle' }>
            <p className='ztAwardsTitleTop'>Awards</p>
            <p className='ztAwardsTitleText'>제타플랜의 인증 및 수상이력</p>
          </div>
          <div className='ztCertiContent'>
            { 
              selectedTab.map(function(a, i){
                return (
                  <div className="ztAwardList" key={a.id}>
                    <h3 className='ztYear'>{selectedTab[i].year}</h3>
                    <p className='ztAwardTitle'>{selectedTab[i].title}</p>
                    <p className='ztAwardContent' dangerouslySetInnerHTML={{__html:selectedTab[i].content}}></p>
                  </div> 
                )
              }) 
            } 
          </div>
        </div>
      </div>
    </div>
  );
};

export default Index;

1.오류 : 위와 같이 코드를 jsx에서 scroll이 1800(적용시키려는 스크롤수치)되었을 때 클래스를 적용시켜 css를 입히려고 하자 오류가 났다.(원인: 기존 레이아웃 위치를 display:flex 로 적용시켰기 때문에 나중에 fixed된 클래스를 입힐 때 위치가 다 바뀌고 float처럼 떠버림 )

 

▼ 해결코드

import React from 'react';
import {useState, useEffect, useRef} from 'react';
import certiUrl from './../../db/certificateList.json';
import awardUrl from './../../db/awardList.json';
import './../../styles/zeta/index.scss';

const Index = () => {
  const [certiData,setCertiData]=useState([]);
  const [awardData,setAwardData]=useState([]);

  const [selectedTab, setSelectedTab] = useState(certiUrl);
  //console.log(certiData);

  
  
  useEffect(()=>{
    setCertiData(certiUrl);
    setAwardData(awardUrl);
  },[])

  /*  */
  

  return (
    <div className='ztInfoBox'>
      <div className='ztIntro'>
        <h2 className='ztTitle'>
          회사소개
        </h2>
        <div className='ztInfoText'>
          <p className='ztTextTitle'>시작과 성장과 안정을 위한 컨설팅 솔루션 </p>
          <p className='ztTextWh'>체계적인 분석과 함께 정확한 대안을 가진 솔루션을 제공<br/>
            기업자금지원지원/기업구구조조정/기업전략컨설팅<br/>
            투자유치와 IPO, M&A 단계에 이를 수 있도록 지원<br/>
            한국 30여개 벤처캐피털과 해외 50여개 PEF 및 벤처캐피털 등과 제휴</p>
          <p className='ztTextGr'>
            안정을 원하는 모든 기업에게 위험을 제거한 최대의 기회만을 제공할 것을 약속드립니다.<br/>
            기업들의 꿈을 제타플랜이 함께 응원하겠습니다.<br/>
            체계적인 서비스로 성공과 안정된 기업으로 만들어 드리겠습니다.
          </p>
        </div>
      </div>

      <div className='ztMessage'>
        <div className='ztMessageInner'>
          <div className='ztMessageBox'>
            <img className='ztCircle' src={require('./../../img/zeta/zeta_circle.png')} alt="circle"/>
            <div className='ztCeoTexts'>
              <h2>CEO'S MESSAGE</h2>
              <p className='ztCeoText'>
                (주)제타플랜인베스트는  “지구상의 모든 기업들의 시작과 성장과 안정을 위한 컨설팅 솔루션 제공”이라는 대명제를 가지고 경영컨설팅 서비스를 제공하고 있습니다. 체계적인 컨설팅 서비스를 통해 기업의 시작과 성장, 안정을 원하는 모든 기업에게 위험을
                제거한 최대의 기회만을 제공할 것을 약속드립니다.
              </p>
              <p className='ztCeoName'>
                CEO/홍현권
              </p>
            </div>
          </div>
          
          <p className='ztCeoImg'>
            <img src={require('./../../img/zeta/zeta_hyunkyun@2x.png')} alt="zt_ceo" />
          </p>
        </div>
      </div>

      <div className='ztAwardsBox'>
        <div className='ztAwardsBoxInner'>
          
          <div className='ztAwardsTab fixed' >
            <p onClick={() => setSelectedTab(certiData)} className={selectedTab===certiData?'ztCertificate active':'ztCertificate'}>인증서</p>
            <p onClick={() => setSelectedTab(awardData)} className={selectedTab===awardData?'ztAward active':'ztAward'}>상장</p>
          </div>
          {/* <div className='ztAwardsTitle'> */}
          <div className= 'ztAwardsTitle fixed'>
            <p className='ztAwardsTitleTop'>Awards</p>
            <p className='ztAwardsTitleText'>제타플랜의 인증 및 수상이력</p>
          </div>
          <div className='ztCertiContent'>
            { 
              selectedTab.map(function(a, i){
                return (
                  <div className="ztAwardList" key={a.id}>
                    <h3 className='ztYear'>{selectedTab[i].year}</h3>
                    <p className='ztAwardTitle'>{selectedTab[i].title}</p>
                    <p className='ztAwardContent' dangerouslySetInnerHTML={{__html:selectedTab[i].content}}></p>
                  </div> 
                )
              }) 
            } 
          </div>
        </div>
      </div>
    </div>
  );
};

export default Index;

1. jsx 에 기존 적용시켰던 scroll효과를 제거

 

2. css를 아래와 같이 작성하자 해결됨 (fixed =>sticky)

.fixed {
 /*  position: fixed;
    left: 35rem;
    top: 8rem; */
    position: sticky; 
    left: 0;
    top:8rem; 
    height: 400px; //--> sticky가 적용될 요소는 꼭 height값이 있어야 함
}

*처음 height값을 안 줬더니 위치가 고정이 안 됨 / 위 코드와 같이 꼭 height값이 있어야 적용 됨

 

위와 같은 방법으로 해결하여

해당 영역부분에서 원하는 왼쪽 title tab은 고정 / 오른쪽 tab내용은 세로로 쭉 스크롤되는 효과 적용 완료