[JS] ํน์  ์์ ์์น๋ก ์คํฌ๋กค ์ด๋ํ๊ธฐ - scrollIntoView
๋ฐ์ํ
    
    
    
  ๋ฌธ๋ฒ
ํน์  ์์๊ฐ ์์นํ ๊ณณ๊น์ง ์คํฌ๋กค์ ์ด๋ํ๊ณ  ์ถ์ ๋ element.scrollIntoView ๋ฉ์๋๋ฅผ ์ด์ฉํ๋ฉด ๊ฐํธํ๊ฒ ๊ตฌํํ  ์ ์๋ค. scrollIntoView ๋ฉ์๋๋ ์ด 3๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก ์ฌ์ฉํ  ์ ์๋ค. (MDN)
element.scrollIntoView(align)
โถ ํ๋ผ๋ฏธํฐ ์์ — element๊ฐ ๋ธ๋ผ์ฐ์  ํ๋ฉด ๊ฐ์ฅ ์๋ก ์ค๋๋ก ์คํฌ๋กค(์ ๋ ฌ)
element.scrollIntoView(); // element.scrollIntoView(true)์ ๋์ผ
โท boolean ํ๋ผ๋ฏธํฐ
// { block: "start", inline: "nearest" } ์ต์
๊ณผ ๋์ผ
element.scrollIntoView(true); 
// { block: "end", inline: "nearest" } ์ต์
๊ณผ ๋์ผ
element.scrollIntoView(false);
true๋ฅผ ๋๊ฒผ์ ๋ : element๊ฐ ๋ธ๋ผ์ฐ์  ํ๋ฉด ๊ฐ์ฅ ์๋ก ์ค๋๋ก ์คํฌ๋กค(์ ๋ ฌ)false๋ฅผ ๋๊ฒผ์ ๋ : element๊ฐ ๋ธ๋ผ์ฐ์  ํ๋ฉด ๊ฐ์ฅ ์๋๋ก ์ค๋๋ก ์คํฌ๋กค(์ ๋ ฌ)
โธ ์ต์  ๊ฐ์ฒด ํ๋ผ๋ฏธํฐ
element.scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'nearest' });
behavior: ์คํฌ๋กค ์ ํ ํจ๊ณผ (๊ธฐ๋ณธ๊ฐauto)
์ต์  :auto,smoothblock: ์์ง ์ ๋ ฌ (๊ธฐ๋ณธ๊ฐstart)
์ต์  :start,end,center,nearestinline: ์ํ ์ ๋ ฌ (๊ธฐ๋ณธ๊ฐnearest)
์ต์  :start,end,center,nearest
๐ก block, inline ์ต์
๊ฐ ์ค๋ช
start: element๊ฐ ๋ธ๋ผ์ฐ์  ํ๋ฉด ๊ฐ์ฅ ์๋ก ์ค๋๋ก ์คํฌ๋กค(์ ๋ ฌ)end: element๊ฐ ๋ธ๋ผ์ฐ์  ํ๋ฉด ๊ฐ์ฅ ์๋๋ก ์ค๋๋ก ์คํฌ๋กค(์ ๋ ฌ)center: element๊ฐ ๋ธ๋ผ์ฐ์  ํ๋ฉด ์ค๊ฐ์ผ๋ก ์ค๋๋ก ์คํฌ๋กค(์ ๋ ฌ)nearest: element์ ๊ฐ๊น์ด ๊ณณ์ผ๋ก ์คํฌ๋กค
ํจ์ ์์ฉ ์์
const moveToTop = () => document.body.scrollIntoView(true); // ์๋จ์ผ๋ก ์ด๋
const moveToBottom = () => document.body.scrollIntoView(false); // ํ๋จ์ผ๋ก ์ด๋
์ปค์คํ  ํ ์ฌ์ฉ ์์
์ปดํฌ๋ํธ โผ
// ์ปดํฌ๋ํธ ๋ณธ๋ฌธ (๋ฐฐ์ด orders, Set ๊ฐ์ฒด selectedOrderIds๋ฅผ prop์ผ๋ก ๋ฐ์)
const tableRowRefs = useRef(
  orders.map(({ order_id }) => ({
    id: order_id,
    element: createRef<HTMLTableRowElement>(), // ref ๊ฐ์ฒด ์ฌ๋ฌ๊ฐ ์์ฑ
  })),
);
useScrollIntoView({
  isActive: selectedOrderIds.size === 1, // true ์ผ๋๋ง ํ์ฑํ
  ref: tableRowRefs.current.find(({ id }) => id === [...selectedOrderIds][0])
    ?.element,
  align: { behavior: 'smooth', block: 'center' }, // align ์ต์
});
return (
  <div>
    {orders.map((order, i, { length }) => (
      <div ref={tableRowRefs.current[i].element}>{/* ... */}</div>
    ))}
  </div>
);
์ปค์คํ  ํ โผ
interface Props {
  isActive: boolean; // useScrollIntoView ํ
 ํ์ฑํ ์ฌ๋ถ
  ref: RefObject<HTMLElement> | undefined;
  align?: ScrollIntoViewOptions; // scrollIntoView ๋ฉ์๋ align ์ต์
}
/** ์ฒซ ๋ ๋๋ง์๋ง ์ ํํ ์๋ฆฌ๋จผํธ๊ฐ ์์นํ ๊ณณ์ผ๋ก ์คํฌ๋กคํ๋ Hook */
export default function useScrollIntoView({ isActive, ref, align }: Props) {
  const isNavigated = useRef(false); // ์์๊ฐ ์๋๊ณณ๊น์ง ์คํฌ๋กค ํ๋์ง ์ฌ๋ถ
  useEffect(() => {
    if (isActive && !isNavigated.current) {
      ref?.current?.scrollIntoView(align);
      isNavigated.current = true; // ์ฒซ ๋ ๋๋ง์๋ง ์คํฌ๋กคํ๊ธฐ ์ํด isNavigated ๊ฐ true๋ก ๋ณ๊ฒฝ
    }
  }, [align, isActive, ref]);
}
๊ธ ์์ ์ฌํญ์ ๋ ธ์  ํ์ด์ง์ ๊ฐ์ฅ ๋น ๋ฅด๊ฒ ๋ฐ์๋ฉ๋๋ค. ๋งํฌ๋ฅผ ์ฐธ๊ณ ํด ์ฃผ์ธ์
๋ฐ์ํ
    
    
    
  '๐ช Programming' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [TS] ํ์ ์คํฌ๋ฆฝํธ์์ CSS Module ์ฌ์ฉํ๊ธฐ (0) | 2024.05.11 | 
|---|---|
| [React] falsy ๊ฐ์ ์ฌ์ฉํ ๋ฆฌ์กํธ ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ์ฃผ์ํ ์  (0) | 2024.05.11 | 
| [React] ๋ฆฌ์กํธ Render Props ํจํด 2๊ฐ์ง ์ฌ์ฉ ๋ฐฉ๋ฒ (0) | 2024.05.11 | 
| [TS] ํ์ ์คํฌ๋ฆฝํธ ํ์ ๊ฐ๋ is / asserts ํค์๋ ์ฐจ์ด์  (0) | 2024.05.10 | 
| [DevTools] ๊ฐ๋ฐ์ ์นํ์ ์ธ ํฐ๋ฏธ๋ LS โ PLS (0) | 2024.05.10 | 
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
- 
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
 - 
์นด์นด์คํก
์นด์นด์คํก
 - 
๋ผ์ธ
๋ผ์ธ
 - 
ํธ์ํฐ
ํธ์ํฐ
 - 
Facebook
Facebook
 - 
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
 - 
๋ฐด๋
๋ฐด๋
 - 
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
 - 
Pocket
Pocket
 - 
Evernote
Evernote
 
๋ค๋ฅธ ๊ธ
- 
[TS] ํ์ ์คํฌ๋ฆฝํธ์์ CSS Module ์ฌ์ฉํ๊ธฐ
[TS] ํ์ ์คํฌ๋ฆฝํธ์์ CSS Module ์ฌ์ฉํ๊ธฐ
2024.05.11 - 
[React] falsy ๊ฐ์ ์ฌ์ฉํ ๋ฆฌ์กํธ ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ์ฃผ์ํ ์ 
[React] falsy ๊ฐ์ ์ฌ์ฉํ ๋ฆฌ์กํธ ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ์ฃผ์ํ ์ 
2024.05.11 - 
[React] ๋ฆฌ์กํธ Render Props ํจํด 2๊ฐ์ง ์ฌ์ฉ ๋ฐฉ๋ฒ
[React] ๋ฆฌ์กํธ Render Props ํจํด 2๊ฐ์ง ์ฌ์ฉ ๋ฐฉ๋ฒ
2024.05.11 - 
[TS] ํ์ ์คํฌ๋ฆฝํธ ํ์ ๊ฐ๋ is / asserts ํค์๋ ์ฐจ์ด์ 
[TS] ํ์ ์คํฌ๋ฆฝํธ ํ์ ๊ฐ๋ is / asserts ํค์๋ ์ฐจ์ด์ 
2024.05.10