0Pricing
React Academy · درس

التلميحات والقوائم المنسدلة باستخدام Portals

استخدموا Portals لتصيير التلميحات والقوائم المنسدلة خارج الحاويات ذات overflow-hidden

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

مرحبًا

ستبني في هذا الدرس مكوّنات للتلميحات والقوائم المنسدلة تستخدم React Portals للعرض داخل document.body، متجاوزةً قيود overflow-hidden وسياقات تكديس z-index الخاصة بالآباء.

مشكلة Overflow

سيُقتصّ التلميح الموضوع بالنسبة إلى زر التشغيل إذا كان لأي سلف `overflow: hidden` أو `overflow: scroll`. ويحل نقل التلميح إلى document.body عبر Portal هذه المشكلة بالكامل.

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

لتحديد موضع تلميح معروض عبر Portal بشكل صحيح، قِس مستطيل إحاطة عنصر التشغيل باستخدام `getBoundingClientRect()`، واحسب الإحداثيات المطلقة مع مراعاة موضع التمرير.
const rect = triggerRef.current.getBoundingClientRect();
const top = rect.bottom + window.scrollY + 8;
const left = rect.left + window.scrollX;

مكوّن Tooltip

أنشئ Tooltip يغلّف children، ويربط ref بعنصر التشغيل، ويعرض عبر Portal صندوق تلميح محدد الموضع عند تمرير المؤشر فوقه.
function Tooltip({ content, children }) {
  const [visible, setVisible] = useState(false);
  const [pos, setPos] = useState({ top: 0, left: 0 });
  const ref = useRef();

  const show = () => {
    const r = ref.current.getBoundingClientRect();
    setPos({ top: r.bottom + window.scrollY + 4,
             left: r.left + window.scrollX });
    setVisible(true);
  };

  return (
    <span ref={ref} onMouseEnter={show} onMouseLeave={() => setVisible(false)}>
      {children}
      {visible && createPortal(
        <div style={{ position:'absolute', top: pos.top, left: pos.left }}
             className="tooltip">{content}</div>,
        document.body
      )}
    </span>
  );
}

تحديث الموضع عند التمرير وتغيير الحجم

إذا مرّر المستخدم الصفحة أثناء ظهور التلميح، يصبح موضعه قديمًا. استمع إلى حدثي `scroll` و`resize` لإعادة حساب الموضع أو إغلاق التلميح.
useEffect(() => {
  if (!visible) return;
  const update = () => setVisible(false);
  window.addEventListener('scroll', update, true);
  window.addEventListener('resize', update);
  return () => {
    window.removeEventListener('scroll', update, true);
    window.removeEventListener('resize', update);
  };
}, [visible]);

بنية القوائم المنسدلة

تتبع القائمة المنسدلة النمط نفسه الذي يتبعه التلميح. يعرض زر التشغيل القائمة أو يخفيها، وتُعرض القائمة عبر Portal، ويغلقها معالج النقر خارجها.

معالج النقر خارج العنصر

استخدم مستمع `mousedown` على `document` لاكتشاف النقرات خارج القائمة. وقارن هدف النقر مع مراجع القائمة وزر التشغيل لتحديد ما إذا كان ينبغي إغلاقها.
useEffect(() => {
  if (!open) return;
  const handler = (e) => {
    if (!menuRef.current?.contains(e.target) &&
        !triggerRef.current?.contains(e.target)) {
      setOpen(false);
    }
  };
  document.addEventListener('mousedown', handler);
  return () => document.removeEventListener('mousedown', handler);
}, [open]);

التنقل باستخدام لوحة المفاتيح في القوائم المنسدلة

نفّذ ArrowDown/ArrowUp للتنقل بين عناصر القائمة، وEnter للاختيار، وEscape للإغلاق. وتتبع فهرس العنصر الذي يملك التركيز في الحالة، واستدعِ `.focus()` برمجيًا على عناصر القائمة.

استخدام مكتبة لتحديد الموضع

في بيئة الإنتاج، استخدم **@floating-ui/react** (المعروفة سابقًا باسم Popper.js). فهي تتعامل تلقائيًا مع flip (إعادة تحديد الموضع قرب حواف إطار العرض) وshift (إبقاء التلميح ظاهرًا) وتحديد موضع السهم.
import { useFloating, flip, shift } from '@floating-ui/react';

const { refs, floatingStyles } = useFloating({
  middleware: [flip(), shift()],
});

إمكانية الوصول: ARIA للتلميحات

بالنسبة إلى التلميحات، أضف `role='tooltip'` إلى عنصر التلميح، وأضف `aria-describedby` الذي يشير إلى معرّف التلميح في عنصر التشغيل. ويتيح ذلك لقارئات الشاشة الإعلان عن محتوى التلميح.
<button aria-describedby="tip1">Hover me</button>
{visible && createPortal(
  <div id="tip1" role="tooltip">Helpful text</div>,
  document.body
)}

تحقق سريع

كيف تحسب موضع الشاشة الصحيح لتلميح معروض عبر Portal؟

مراجعة

تتيح Portals لتلميحات الأدوات والقوائم المنسدلة تجاوز العناصر الأب ذات `overflow-hidden`. قِس العنصر المُشغِّل باستخدام `getBoundingClientRect`، وأضف إزاحات التمرير عند استخدام التموضع المطلق، وأغلق العنصر عند النقر خارجه أو التمرير، وأضف سمات ARIA لإتاحة الوصول.

اكتمل المقرر

تهانينا! لقد أتممت **Portals & Modals in React**. يمكنك الآن إنشاء نوافذ منبثقة وتلميحات أدوات وقوائم منسدلة سهلة الوصول وموضوعة بشكل صحيح، وتتجاوز أي قيود على تكديس CSS.

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

هل درس «التلميحات والقوائم المنسدلة باستخدام Portals» مجاني؟

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

ماذا ستتعلم في «التلميحات والقوائم المنسدلة باستخدام Portals»؟

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

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

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

كم من الوقت يستغرق درس «التلميحات والقوائم المنسدلة باستخدام Portals»؟

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

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

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

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

  1. ما هي React Portals؟
  2. إنشاء مكوّن Modal باستخدام Portals
  3. التعامل مع التركيز ومصائد لوحة المفاتيح في النوافذ المنبثقة
  4. التلميحات والقوائم المنسدلة باستخدام Portals
← العودة إلى React Academy