تغییر کلاس فعال در نوار کناری React با استفاده از IntersectionObserver

react sidebar active class intersectionobserver
20 آبان 1403

در این مقاله می‌خواهیم به بررسی راهی ساده و کارآمد برای مدیریت کلاس‌های فعال در نوار کناری یک برنامه React بپردازیم. در مخیط‌های ریسپانسیو و در هنگام ایجاد نوار کناری‌های هوشمند، یکی از نیازهای مهم، تشخیص موقعیت کاربر بر روی صفحه است. این امر می‌تواند به کاربر کمک کند تا بفهمد در چه قسمتی از صفحه قرار دارد و تجربه کاربری بهتری داشته باشد.

یکی از روش‌های جالب و مدرن حل این مسئله، استفاده از IntersectionObserver API است. این API به ما اجازه می‌دهد به صورت همزمان منابع را مشاهده کنیم و آن‌ها را تغییر دهیم یا استایل خاصی به آن‌ها بدهیم. برای مثال، می‌توانیم زمانی که یک بخش از صفحه‌ی ما درون دید کاربر قرار می‌گیرد، کلاس فعال را به مرجع مربوطه در نوار کناری اختصاص دهیم.

قابلیت اصلی IntersectionObserver در این است که می‌تواند تشخیص دهد آیا عنصری در صفحه نمایش داده شده است یا خیر. بنابراین، با استفاده از این ابزار می‌توانیم بدون نیاز به راه‌حل‌های قدیمی‌تری نظیر event listeners بر اساس اسکرول کار کنیم، که به طور کلی باعث افزایش کارایی و کاربرپسندی صفحه می‌شود.

در این مثال، نشان خواهیم داد که چگونه می‌توان با استفاده از IntersectionObserver، کلاس فعال را به نوار کناری خود اضافه کنیم و این کار را در یک پروژه واقعی پیاده‌سازی می‌کنیم. بنابراین، شما خواهید دید چگونه می‌توانید از کد ارائه شده به طور مستقیم در پروژه‌های خود بهره‌برداری کنید.

در ادامه یک نمونه کد کاربردی را با هم بررسی می‌کنیم:

import React, { useEffect, useRef, useState } from 'react';

const Sidebar = () => {
const sections = useRef([]);
const [activeSection, setActiveSection] = useState('');

useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setActiveSection(entry.target.id);
}
});
},
{ threshold: 0.7 }
);

sections.current.forEach((section) => {
observer.observe(section);
});

return () => {
observer.disconnect();
};
}, []);

return (
<div className="sidebar">
<ul>
<li className={activeSection === 'section1' ? 'active' : ''}>Section 1</li>
<li className={activeSection === 'section2' ? 'active' : ''}>Section 2</li>
<li className={activeSection === 'section3' ? 'active' : ''}>Section 3</li>
</ul>
</div>
);
};

export default Sidebar;

توضیحات کد:

import React, { useEffect, useRef, useState } from 'react';

ایمپورت کردن توابع مورد نیاز از کتابخانه React
const Sidebar = () => {

تعریف کامپوننت Sidebar
const sections = useRef([]);

یک رفرنس برای ذخیره بخش‌های صفحه ایجاد می‌کنیم
const [activeSection, setActiveSection] = useState('');

یک State برای ذخیره شناسه بخشی که در حال حاضر فعال است
useEffect(() => {

استفاده از useEffect برای تنظیم و مدیریت IntersectionObserver
const observer = new IntersectionObserver((entries) => { ... }, { threshold: 0.7 });

تعریف یک ناظر جدید که بر روی عناصر صفحه نظارت داشته باشد
sections.current.forEach((section) => { observer.observe(section); });

تمام بخش‌های صفحه را در ناظر ثبت می‌کنیم
return () => { observer.disconnect(); };

قطع ارتباط ناظر پس از خروج از کامپوننت
return (<div className="sidebar"> ... </div>);

ساختار JSX برای نمایش نوار کناری
export default Sidebar;

صادر کردن کامپوننت Sidebar برای استفاده در سایر بخش‌های برنامه

سوالات متداول

؟

چرا از IntersectionObserver برای تغییر کلاس‌ها استفاده می‌کنیم؟

؟

آیا می‌توان همزمان از چند ناظر استفاده کرد؟

؟

چگونه می‌توان مرزهای مختلف را برای فعال‌سازی کلاس تنظیم کرد؟