0Pricing
HTML Academy · درس

تنفيذ التمرير اللانهائي

تحميل المزيد من المحتوى تلقائيًا أثناء تمرير المستخدم

تنفيذ التمرير اللانهائي درس مجاني في HTML Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في HTML Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة HTML Academy 4 دروس في المجموع.

النمط

يحمّل التمرير اللانهائي مزيدًا من المحتوى عندما يقترب المستخدم من أسفل القائمة. ويستخدم التنفيذ الأنظف IntersectionObserver: ضع عنصر «sentinel» في نهاية القائمة وراقبه. وعندما يدخل sentinel إلى إطار العرض، اجلب الصفحة التالية.

عنصر sentinel

أضف عنصر <div> غير مرئي (أو عنصرًا نائبًا يعرض «جارٍ التحميل...») بعد آخر عنصر في القائمة. راقبه باستخدام IntersectionObserver. وعندما يحدث تقاطع معه، فهذا يعني أن المستخدم مرر قريبًا من الأسفل، وحان وقت جلب المزيد.

<ul id="feed">
  <li>Post 1</li>
  <li>Post 2</li>
</ul>
<div id="sentinel" aria-hidden="true"></div>

حلقة المراقب

عند حدوث التقاطع: اجلب الصفحة التالية، واعرض العناصر الجديدة، وأعد وضع sentinel (فسيبقى تلقائيًا في نهاية القائمة إذا أضفت العناصر قبله). ولا حاجة إلى إيقاف المراقبة ثم إعادة تشغيلها؛ فما زال sentinel خاضعًا للمراقبة.

const sentinel = document.getElementById("sentinel");
const feed = document.getElementById("feed");
let page = 1;
let loading = false;
const observer = new IntersectionObserver(async (entries) => {
  if (!entries[0].isIntersecting || loading) return;
  loading = true;
  const items = await fetchPage(page++);
  items.forEach((it) => feed.insertAdjacentHTML("beforeend", renderItem(it)));
  loading = false;
});
observer.observe(sentinel);

حارس حالة التحميل

يمنع مؤشر منطقي loading تكديس الطلبات إذا مرر المستخدم بسرعة وتسبب في حدوث تقاطعات متعددة قبل وصول الاستجابة الأولى. ومن دونه، تُجلب الصفحة نفسها مرارًا وتظهر العناصر مكررة.

نهاية البيانات

عندما يعيد الخادم صفحة فارغة (أو يشير إلى «لا مزيد من البيانات»)، أوقف مراقبة sentinel واستبدله برسالة تفيد بالوصول إلى نهاية القائمة. ولن تؤدي التقاطعات المستقبلية إلى تشغيل عمليات الجلب، وسيرى المستخدم أنه وصل إلى النهاية.

معالجة الأخطاء

ضع fetch داخل try/catch. عند حدوث خطأ، اترك loading = true حتى لا تُشغّل عمليات إعادة المحاولة تلقائيًا؛ واعرض زر «إعادة المحاولة» يعيد ضبط loading ويشغّل التحميل من جديد. فمن دون ذلك، قد تؤدي أعطال الشبكة إلى عاصفة من عمليات إعادة المحاولة.

rootMargin للتحميل المبكر

يبدأ rootMargin: "500px" جلب الصفحة التالية قبل وصول المستخدم إلى sentinel بمقدار 500 بكسل. اضبطه استنادًا إلى ارتفاع العناصر ومتوسط سرعة التمرير؛ فإذا كان صغيرًا جدًا، سيصل المستخدمون إلى رسالة «لا يوجد محتوى بعد»، وإذا كان كبيرًا جدًا، فستجلب محتوى قبل الحاجة إليه.

استعادة موضع التمرير

عندما يغادر المستخدم الصفحة ويعود إليها، ينبغي الحفاظ على موضع التمرير وإعادة عرض العناصر التي حُمّلت سابقًا أيضًا. خزّن العناصر في sessionStorage أو في مخزن بأسلوب Zustand، واستعدها عند تحميل المكوّن ثم استخدم scrollTo للانتقال إلى الإزاحة المحفوظة.

اعتبارات الذاكرة

تراكم عمليات التمرير اللانهائي الطويلة آلاف عقد DOM. وبالنسبة إلى الخلاصات الطويلة جدًا مثل Twitter وFacebook، ادمجها مع windowing: أزل العناصر الموجودة فوق إطار العرض من DOM، وأعدها عند التمرير إلى الأعلى. تتولى مكتبات مثل react-virtual و@tanstack/virtual ذلك بكفاءة.

إمكانية الوصول

يُعد التمرير اللانهائي معاديًا لمستخدمي لوحة المفاتيح وقارئات الشاشة الذين لا يستطيعون الوصول بسهولة إلى تذييل الصفحة. وفر زر «تحميل المزيد» كحل بديل، وتأكد من أن الصفحة تحتوي على تذييل حقيقي يمكن الوصول إليه باستخدام مفتاحي Home وEnd. كما يساعد إعلان العناصر الجديدة عبر منطقة aria-live.

التمرير الارتدادي على الأجهزة المحمولة

قد يؤدي التمرير الارتدادي في iOS إلى حدوث تقاطعات متعددة قرب الأسفل. يعالج حارس التحميل معظم الحالات؛ وقد ترغب أيضًا في تطبيق debounce لمدة 300 مللي ثانية لتصفية دفعة التقاطعات التي تحدث أثناء الارتداد.

بديل: التقسيم إلى صفحات باستخدام cursor

ينبغي أن تعيد واجهات API الخادمية «next cursor» بدلًا من الاعتماد على أرقام الصفحات التي يتتبعها العميل، لأن ذلك أكثر متانة في مواجهة إدراج العناصر أو حذفها أثناء التمرير. يرسل العميل cursor في كل طلب، ويتوقف عندما لا يعيد الخادم cursor.

اختبار المعرفة

لماذا تكون علامة "loading" ضرورية في دالة الاستدعاء الخاصة بـ IntersectionObserver عند تنفيذ التمرير اللانهائي؟

ملخص

يستخدم التمرير اللانهائي كائن IntersectionObserver مع عنصر sentinel في نهاية القائمة. عند حدوث التقاطع، اجلب الصفحة التالية واعرضها، ثم واصل مراقبة العنصر. استخدم علامة loading للحماية، وتعامل بسلاسة مع نهاية البيانات والأخطاء، واضبط rootMargin لتحديد مسافة الجلب المسبق. وفّر بدائل باستخدام لوحة المفاتيح، مثل زر «تحميل المزيد»، وفكّر في استخدام windowing للخلاصات الطويلة جدًا.

الأسئلة الشائعة

هل درس «تنفيذ التمرير اللانهائي» مجاني؟

نعم — نص درس «تنفيذ التمرير اللانهائي» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة HTML Academy، انتقل إلى CoddyKit PRO. تتضمن دورة HTML Academy 4 دروس في المجموع.

ماذا ستتعلم في «تنفيذ التمرير اللانهائي»؟

تحميل المزيد من المحتوى تلقائيًا أثناء تمرير المستخدم تتمرن على HTML Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ HTML Academy؟

لا تُشترط خبرة سابقة. HTML Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «تنفيذ التمرير اللانهائي»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس HTML Academy هذا؟

نعم. كل درس في HTML Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. IntersectionObserver API والعتبات
  2. التحميل الكسول باستخدام IntersectionObserver
  3. تنفيذ التمرير اللانهائي
  4. إعداد الرسوم المتحركة المرتبطة بالتمرير
← العودة إلى HTML Academy