728x90
개요
상품이 많아지게 된다면 스크롤을 하게 되면 헤더가 안보이게 되는데 최근 웹페이지의 트렌드는 헤더가 같이 따라오는것이 트렌드라 반응형 Header를 제작하도록 하겠습니다.
스크롤이벤트 추가하기
Home.js
import React , {useState , useEffect ,useRef} from 'react';
import styled from 'styled-components';
/* Header import */
import Header from '../components/Header/Header';
/* Top import */
import Top from '../components/Top/Top';
/* Nav import */
import Nav from '../components/Nav/Nav';
/* Item import */
import Item from '../components/Item/Item';
/* Footer import */
import Footer from '../components/Footer/Footer';
function Home(){
const [pcategory , setPcategory] = useState('animal')
const clickPcategory = (pcategory) => {
setPcategory(pcategory)
}
/*스크롤 이벤트 */
const [ScrollY, setScrollY] = useState(0); // window 의 pageYOffset값을 저장
const [ScrollActive, setScrollActive] = useState(false);
const handleScroll = () => {
if(ScrollY > 120) {
setScrollY(window.pageYOffset);
setScrollActive(true);
} else {
setScrollY(window.pageYOffset);
setScrollActive(false);
}
}
useEffect(() => {
function scrollListener() { window.addEventListener("scroll", handleScroll); } // window 에서 스크롤을 감시 시작
scrollListener(); // window 에서 스크롤을 감시
return () => { window.removeEventListener("scroll", handleScroll); }; // window 에서 스크롤을 감시를 종료
});
return(
<>
<Container>
<Top ScrollActive={ScrollActive} />
<Header ScrollActive={ScrollActive}/>
<Nav pcategory={pcategory} clickPcategory={clickPcategory} />
<Item pcategory={pcategory} ScrollActive={ScrollActive}/>
</Container>
<Footer />
</>
)
}
export default Home;
const Container = styled.div`
position: relative;
padding: 0px;
border: 0px;
width : 100%;
height: 200%;
`
Home 페이지에 스크롤 이벤트를 작성해줍니다. ScrollY 값이 120 이상이면 ScrollActive가 true값이 되면서 css 값을 바꾸게 해줄것입니다.
Top.js
import React ,{useState} from 'react'
import styled from 'styled-components';
export default function Top({ScrollActive}){
const [login,setLogin] = useState(false)
return(
<Positioner className={ScrollActive ? 'flexible' : null}>
<GreyBackground>
<TopContents>
<Spacer />
<P>홈</P>
<Spacer />
{login === false ?
<>
<P>회원가입</P>
<P>로그인</P>
</>
:
// 로그인 했을 때
<>
<P></P>
<P>로그아웃</P>
</>}
</TopContents>
</GreyBackground>
</Positioner>
)
}
// 상단 고정
const Positioner = styled.div`
display: flex;
flex-direction: column;
position: absolute;
top: 0px;
left : calc(50vw - 600px);
width: 1300px;
z-index:99;
padding : 0px;
border: 0px;
&.flexible{
position: fixed;
background : #e2e2e2;
height: 40px;
}
`;
// 회색 배경
const GreyBackground = styled.div`
flex-direction: row;
align-items: center;
`
const TopContents = styled.div`
width: 1200px;
height: 30px;
display : inline-grid;
flex-direction: row;
align-items: right;
grid-template-columns: 220px 50px 600px 90px 100px;
`
//글씨
const P = styled.span`
margin: 5px;
font-family : 'tway';
`
//여백
const Spacer = styled.div`
`
ScrollActive 를 props로 받아와 조건이 만족할때 포지션값을 바꿔줍니다.
Header.js
import React from "react";
import styled from "styled-components";
export default function Header({ScrollActive}){
return(
<Positioner className={ScrollActive ? 'flexible' : null}>
<WhiteBackground>
<HeaderContents>
<Spacer/>
<Title>Furry</Title>
<Search>
<Input
placeholder="찾고 싶은 상품을 검색해보세요!"/>
<IMG> 🔎 </IMG>
</Search>
<MY className={ScrollActive ? 'flexible' : null}>
<ICON>😀</ICON>
<P>마이퓨리</P>
</MY>
<Cart className={ScrollActive ? 'flexible' : null}>
<ICON>🛒</ICON>
<P>장바구니</P>
</Cart>
<Spacer/>
</HeaderContents>
</WhiteBackground>
</Positioner>
)
}
// 상단 고정, 그림자
const Positioner = styled.div`
display: flex;
flex-direction: column;
position: absolute;
top: 35px;
left : calc(50vw - 600px);
width: 1300px;
padding : 0px;
border: 0px;
z-index:99;
&.flexible{
position: fixed;
background : #e2e2e2;
height: 60px;
}
`
// 흰 배경, 내용 중간 정렬
const WhiteBackground = styled.div`
display: flex;
justify-content: center;
height: auto;
`
// 해더의 내용
const HeaderContents = styled.div`
width: 1200px;
height: 55px;
display: flex;
flex-direction: row;
align-items: center;
`
// 로고
const Title = styled.div`
font-size: 2rem;
letter-spacing: 5px;
font-family: 'tway';
margin: 30px;
`
//검색창
const Search = styled.div`
margin: 30px;
position: relative;
width: 450px;
`
const Input = styled.input`
width: 400px;
height: 30px;
border : 3px solid #8ec64e;
border-radius : 24px;
outline: none;
padding-left: 10px;
`
const IMG = styled.span`
position: absolute;
top : 7px;
right : 45px;
margin: 0;
`
//장바구니
const MY = styled.button`
margin: 5px;
border : 0px;
line-height: 0;
overflow : hidden;
background: #e2e2e2;
&.flexible{
background: transparent;
}
`
const Cart = styled.button`
margin: 5px;
border : 0px;
line-height: 0;
background: #e2e2e2;
&.flexible{
background: transparent;
}
`
const ICON = styled.p`
font-size : 2rem;
`
const P = styled.p`
font-weight : 1000;
`
// 중간 여백
const Spacer = styled.div`
flex-grow: 1;
`;
Item 렌더링 될때 처음에 보여줄 컴포넌트
아직 정한것이 없어 모든 상품을 보여주도록 했다.
Item.js
import React, { useState } from "react";
import styled from "styled-components";
/*상품 불러오기*/
import product from '../../JSON/product.json'
function ItemList({item,pcategory}){
// console.log(Object.keys(product.product).length)
return(
<>
{item.pcategory.includes(pcategory)
?
<Frame>
<Img src='' alt='x' />
<Name>
{item.pname}
</Name>
<Price>
{item.pprice}
</Price>
</Frame>
:
<>
</>
}
</>
)
}
function AllItemList({item}){
// console.log(Object.keys(product.product).length)
return(
<>
{item
?
<Frame>
<Img src='' alt='x' />
<Name>
{item.pname}
</Name>
<Price>
{item.pprice}
</Price>
</Frame>
:
<>
</>
}
</>
)
}
export default function Item({pcategory , ScrollActive}){
return(
<Positioner className={ScrollActive ? 'flexible' : null}>
{pcategory !== 'animal' ?
<>
{product.product.map((item)=>
<ItemList item={item} id={item.id} pcategory={pcategory} />)}
</>
:
<>
{product.product.map((item)=>
<AllItemList item={item} id={item.id} />)}
</>
}
</Positioner>
)
}
const Positioner = styled.div`
display: block;
flex-direction: column;
position: absolute;
top: 220px;
left : calc(50vw - 400px );
width: calc(100vw - (50vw - 400px) * 2 );
@media (min-width : 1200px){
left : calc(50vw - 600px );
width: calc(100vw - (50vw - 600px) * 2 );
}
height: fit-content;
padding : 0px;
padding-bottom : 5rem;
border: 0px;
background-color: #FFFFFF;
&.flexible{
}
`;
const Frame = styled.div`
display: inline-block;
/*부모 요소에 따라 크기 변경 => %*/
width: 30%;
height: 300px;
margin-left : 2.5%;
margin-top : 2.5%;
@media (min-width : 1200px){
width: 18%;
/*광기*/
margin-left : 1.666666666666667%;
}
border-radius: 10px;
background: #fffaf2;
box-shadow: 1px 1px 2px #bebebe, -1px -1px 2px #ffffff;
`
const Img = styled.img`
width: 90%;
height: 65%;
margin: 5%;
display: block;
`
const Name = styled.p`
padding-left : 5px;
font-family : 'tway';
`
const Price = styled.p`
padding-left : 5px;
font-family : 'tway';
`
728x90
'React > Furry' 카테고리의 다른 글
| 10-2 ItemDetail 페이지 만들기 (1) | 2023.02.27 |
|---|---|
| 10-1. ItemDetail 페이지 만들기 (0) | 2023.02.15 |
| 8. Item 제작하기 (0) | 2023.02.10 |
| 7. Props 흐름 수정하기 (0) | 2023.02.08 |
| 6. NavDetail 제작하기 (0) | 2023.02.08 |