๐Ÿ‘ฉโ€๐Ÿ’ป/React

[React.js๋กœ ๋งŒ๋“œ๋Š” Tech Blog] #4 Window.scrollY/window.pageYOffset

ํ•œ๋‚˜ 2021. 2. 21. 01:11

2021/02/09 - [๐Ÿ‘ฉโ€๐Ÿ’ป/React.js] - [React.js๋กœ ๋งŒ๋“œ๋Š” Tech Blog] #1 Figma ํ”„๋กœํ† ํƒ€์ดํ•‘/๊ฐœ๋ฐœํ™˜๊ฒฝ ์„ธํŒ…/Grommet UI Library/useState/Responsive Header ๋งŒ๋“ค๊ธฐ

2021/02/13 - [๐Ÿ‘ฉโ€๐Ÿ’ป/React.js] - [React.js๋กœ ๋งŒ๋“œ๋Š” Tech Blog] #2 react router ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ™œ์šฉ

2021/02/16 - [๐Ÿ‘ฉโ€๐Ÿ’ป/React.js] - [React.js๋กœ ๋งŒ๋“œ๋Š” Tech Blog] #3 master ๋ธŒ๋žœ์น˜๋กœ ํ†ตํ•ฉํ•˜๊ธฐ/github pages์— ์žฌ๋ฐฐํฌํ•˜๊ธฐ


์ด์Šˆ

์ž‘์—…๋ฌผ์˜ Preview ์ด๋ฏธ์ง€๋ฅผ ํด๋ฆญํ•˜๋ฉด ํ™•๋Œ€๋˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ–ˆ๋Š”๋ฐ, ์ด๋ฏธ์ง€๋ฅผ ๋‹ซ๊ณ  ์›๋ž˜ ํŽ˜์ด์ง€๋กœ ๋Œ์•„์˜ค๋ฉด, ๋ธŒ๋ผ์šฐ์ € ์ƒ๋‹จ์œผ๋กœ ์˜ฌ๋ผ๊ฐ€๋Š” ์ด์Šˆ๊ฐ€ ์žˆ์—ˆ๋‹ค. ๋ชจ๋ฐ”์ผ ๋ทฐ์—์„œ๋งŒ ํ•ด๋‹น ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์ง€๋งŒ, ์‚ฌ์šฉํ•˜๋Š” UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํƒœ๊ทธ ๋ฌธ์ œ์ธ ๋“ฏํ–ˆ๋‹ค.

overlay๋ฅผ ์‹œ์ž‘ํ•  ๋•Œ state๋กœ ํ˜„์žฌ window.scrollY ์œ„์น˜ ๊ฐ’์„ ์ €์žฅํ•˜๊ณ , Close ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ๋ฅผ ๋น ์ ธ๋‚˜์˜ฌ ๋•Œ ๊ทธ ์œ„์น˜๋กœ ๋Œ์•„๊ฐ€๋„๋ก ํ–ˆ๋‹ค.

ํ•ด๊ฒฐ

function returnYOffset(y) {
if (window.pageYOffset === 0) {
window.scrollTo(0, y);
}
}
const Preview = (props) => {
const [show, setShow] = useState();
const [yOffSet, setYOffSet] = useState();
return (
<Box tag='article'
direction='row'
flex
align='center'
margin={{top: 'small', bottom: 'small'}}
border={{side: 'all', color: 'dark-2'}}
round
pad='small'
style={{
width: '100%',
height: 'auto',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
overflow: 'hidden',
}}
>
<Image
src={props.image.src}
alt={props.image.alt}
onClick={() => {
setYOffSet(window.pageYOffset);
setShow(true)
}}
style={{
flexShrink: '0',
maxWidth: '100%',
maxHeight: '100%',
borderRadius: '12px',
}}
/>
{show && (
<Layer
onEsc={() => {
setShow(false);
returnYOffset(yOffSet)
}}
onClickOutside={() => {
setShow(false)
returnYOffset(yOffSet)
}}
margin='xlarge'
>
<Box
pad='small'
direction='column'
flex
background='paper'
>
<Image
fit='contain'
src={props.image.src}
alt={props.image.alt}
style={{borderRadius: '12px', paddingTop: '1rem'}}
/>
<Box
pad='small'
alignSelf='end'
>
<Button
style={{ width: '100%'}}
primary
hoverIndicator='light-1'
color='logoGreen'
label='close'
onClick={(e) => {
setShow(false)
returnYOffset(yOffSet)
}} />
</Box>
</Box>
</Layer>
)}
</Box>
)}
view raw layer.js hosted with โค by GitHub

article ํƒœ๊ทธ ๋‚ด์— image ํƒœ๊ทธ๊ฐ€ ์กด์žฌํ•œ๋‹ค. preview ์ปดํฌ๋„ŒํŠธ๋Š” useState๋ฅผ ์ด์šฉํ•ด์„œ show, yOffSet๋ฅผ ๊ฐ€์ง„๋‹ค. show๊ฐ€ true์ผ ๊ฒฝ์šฐ overlay๋ฅผ ๋„์šฐ๋Š”๋ฐ, Grommet์ด ์ œ๊ณตํ•˜๋Š” <Layer> ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ–ˆ๋‹ค.
<Layer> ํƒœ๊ทธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ onEsc, onClickOutside๋ฅผ ํ†ตํ•ด ํ™”๋ฉด ๋ฐ”๊นฅ๊ณผ ESC ํ‚ค๋ฅผ ์ด์šฉํ•ด overlay๋ฅผ ๋น ์ ธ๋‚˜์˜ค๋„๋ก ํ•œ๋‹ค. ๋‚˜๋Š” ๋ฒ„ํŠผ์„ ํ•˜๋‚˜ ๋” ๋„ฃ์–ด onClick ์ด๋ฒคํŠธ๋„ ๋งŒ๋“ค์–ด์ฃผ์—ˆ๋‹ค.

๊ฐ๊ฐ ๋น ์ ธ๋‚˜์˜ฌ ๋•Œ show ๊ฐ’์„ false,๋กœ, returnYOffset์ด๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋„๋ก ํ–ˆ๋‹ค.

์ฒ˜์Œ window.scrollY๋ฅผ ์“ฐ๋ ค๊ณ  ํ–ˆ๋Š”๋ฐ MDN์„ ํ™•์ธํ•ด๋ณด๋‹ˆ, scrollY์˜ ๋‹ค๋ฅธ ์ด๋ฆ„์˜ ์†์„ฑ์ด์ง€๋งŒ, ๋ธŒ๋ผ์šฐ์ € ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•ด window.pageYOffset์„ ์ œ์•ˆํ•˜๊ณ  ์žˆ์—ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ IE 9 ๋ฏธ๋งŒ์˜ ์˜ฌ๋“œ ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ๋‘ ์†์„ฑ ๋ชจ๋‘ ์ง€์›์ด ์•ˆ ๋œ๋‹ค.

window.scrollY / window.pageYOffset

์›์ ์œผ๋กœ๋ถ€ํ„ฐ ๋ฌธ์„œ๋ฅผ ์ˆ˜์ง๋ฐฉํ–ฅ์œผ๋กœ ์Šคํฌ๋กคํ•œ ํ”ฝ์…€์˜ ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ’. ์–‘์˜ ๊ฐ’ = ์œ„์ชฝ ์Šคํฌ๋กค
๋ฌธ์„œ๊ฐ€ ์œ„๋‚˜ ์•„๋ž˜๋กœ ์ „ํ˜€ ์›€์ง์ด์ง€ ์•Š์€ ์ƒํƒœ๋ผ๋ฉด 0์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

window.pageYOffset === window.scrollY // always returns true