본문으로 건너뛰기

Infinite Scroll

needPanelThreshold 옵션과 needPanel 이벤트로 무한 스크롤을 구현합니다.

import Flicking from "@egjs/flicking";
import "@egjs/flicking/dist/flicking.css";
import "./styles.css";

const COLORS = ["#3e8ed0", "#00d1b2", "#f14668", "#ffe08a", "#48c78e", "#9c27b0", "#ff5722"];
let nextId = 5;

const flicking = new Flicking("#flick", {
  align: "prev",
  needPanelThreshold: 100
});

function addLog(message) {
  const logEl = document.getElementById("event-log");
  const div = document.createElement("div");
  div.textContent = message;
  logEl.appendChild(div);
  // Keep only last 5 entries
  while (logEl.children.length > 5) {
    logEl.removeChild(logEl.firstChild);
  }
}

function updateCounter() {
  const count = flicking.panelCount;
  document.getElementById("panel-count").textContent = count;
}

flicking.on("needPanel", e => {
  addLog(`needPanel: direction=${e.direction}`);

  if (e.direction === "NEXT") {
    // NEXT: append panels
    const newPanels = [];
    for (let i = 0; i < 3; i++) {
      const panel = document.createElement("div");
      panel.className = "flicking-panel";
      panel.style.background = COLORS[nextId % COLORS.length];
      panel.textContent = `Panel ${nextId + 1}`;
      newPanels.push(panel);
      nextId++;
    }
    flicking.append(newPanels);
    addLog(`Added: Panel ${nextId - 3}, ${nextId - 2}, ${nextId - 1}`);
    updateCounter();
  }
});

flicking.on("ready", updateCounter);

요약

주요 옵션

옵션타입기본값설명
needPanelThresholdnumber0needPanel 이벤트 발생 임계값 (px)

관련 이벤트

이벤트설명
needPanel뷰포트 끝에 빈 공간이 보일 때 발생

임계값별 비교

needPanelThreshold동작
0 (기본값)끝에 완전히 도달해야 이벤트 발생
100끝에서 100px 전에 이벤트 발생 (프리로딩)
200끝에서 200px 전에 이벤트 발생

상세 설명

동작 원리

  1. 스크롤하여 뷰포트 끝에 가까워짐
  2. needPanelThreshold 거리 내에 들어오면 needPanel 이벤트 발생
  3. 이벤트 핸들러에서 새 패널 추가
  4. 계속 스크롤 가능
<Flicking
needPanelThreshold={100}
onNeedPanel={(e) => {
if (e.direction === "NEXT") {
// 뒤에 패널 추가
setPanels(prev => [...prev, newPanel]);
}
}}
>
{panels.map(p => <Panel key={p.id} />)}
</Flicking>

needPanel 이벤트

interface NeedPanelEvent {
direction: "PREV" | "NEXT";
}
  • direction으로 어느 방향에 패널이 필요한지 확인
  • "PREV": 앞에 패널 추가 필요 (prepend)
  • "NEXT": 뒤에 패널 추가 필요 (append)

Vanilla JS에서 패널 추가

flicking.on("needPanel", (e) => {
if (e.direction === "NEXT") {
const newPanel = document.createElement("div");
newPanel.className = "flicking-panel";
newPanel.textContent = "New Panel";
flicking.append(newPanel);
}
});

사용 시나리오

언제 needPanelThreshold를 사용하나요?

사용 권장:

  • 무한 스크롤 구현
  • 페이지네이션 (끝에 도달하면 다음 페이지 로드)
  • 대량 데이터의 점진적 로딩

적절한 임계값:

  • 0: 끝에 정확히 도달해야 할 때
  • 100~200: 일반적인 프리로딩
  • 뷰포트 너비 이상: 매우 공격적인 프리로딩

주의사항

이벤트 중복 발생

패널 추가 중에 needPanel 이벤트가 다시 발생할 수 있습니다. 로딩 상태를 관리하여 중복 요청을 방지하세요.

const [isLoading, setIsLoading] = useState(false);

const handleNeedPanel = async (e) => {
if (isLoading) return; // 중복 방지
setIsLoading(true);

await loadMorePanels();

setIsLoading(false);
};

관련 링크

관련 이벤트

관련 메서드

관련 데모