ResizeObserver - أداة قوية جديدة للعمل مع القدرة على التكيف

يوم جيد يا اصدقاء!

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

القليل من التاريخ


في السابق ، كان لدينا فقط استفسارات عن الوسائط تحت تصرفنا - حل CSS يعتمد على حجم ونوع ودقة شاشة جهاز الوسائط (بواسطة جهاز وسائط ، أعني جهاز كمبيوتر أو هاتف أو جهاز لوحي). استعلامات الوسائط مرنة للغاية وسهلة الاستخدام. لفترة طويلة ، كانت استعلامات الوسائط متاحة فقط في CSS ، وهي الآن متاحة أيضًا في JS من خلال window.matchMedia (mediaQueryString). الآن يمكننا التحقق من الجهاز الذي يتم عرض الصفحة ، وكذلك مراقبة التغيير في حجم منطقة العرض (نحن نتحدث عن طريقة MediaQueryList.addListener () - تقريبًا.

استعلامات العنصر


ما افتقرنا إليه هو القدرة على مراقبة حجم عنصر DOM واحد ، وليس فقط إطار العرض بأكمله. يشكو المطورون من هذا لسنوات عديدة. هذه واحدة من أكثر الميزات المتوقعة. في عام 2015 ، تم تقديم اقتراح حتى - طلبات أحجام الحاويات ( استعلامات الحاوية ):
غالبًا ما يحتاج المطورون إلى القدرة على تصميم العناصر عند تغيير حجم الحاوية الرئيسية الخاصة بهم ، بغض النظر عن منطقة العرض. طلبات أحجام الحاويات تمنحهم هذه الفرصة. مثال لاستخدام CSS:
.element : شاشة الوسائط (min-width: 30em) {***}
يبدو الأمر رائعًا ، ولكن كان لدى بائعي المتصفح سبب وجيه لرفض هذا الاقتراح - التبعية الدائرية (التبعية الدائرية) (عندما يحدد حجم ما حجمًا آخر ، يؤدي ذلك إلى حلقة لا نهائية (يمكن العثور على المزيد حول هذا هنا ). ما هي الخيارات الأخرى هناك؟ يمكننا استخدام window.resize (رد الاتصال) ، ولكن هذه "متعة باهظة الثمن" - سيتم استدعاء رد الاتصال في كل مرة يحدث فيها حدث ، وسنحتاج إلى الكثير من الحسابات لتحديد أن حجم المكون قد تغير بالفعل ...

عنصر مراقبة تغيير الحجم باستخدام ResizeObserver API


تعرف على ResizeObserver API من Chrome:
واجهة برمجة تطبيقات ResizeObserver هي واجهة لتتبع تغيير حجم العنصر. هذا هو نوع من التناظرية للحدث window.resize لعنصر.

واجهة برمجة تطبيقات ResizeObserver هي مسودة مباشرة. يتم تنفيذه بالفعل في Chrome و Firefox و Safari للكمبيوتر الشخصي. دعم الجوال أقل إثارة للإعجاب - فقط Chrome على Android و Samsung Internet. لسوء الحظ ، لا توجد نسخة كاملة من polyphile. تحتوي الأشكال المتعددة المتاحة على بعض القيود (على سبيل المثال ، استجابة بطيئة لتغيير الحجم أو نقص الدعم للانتقال السلس). ومع ذلك ، لا ينبغي أن يمنعنا هذا من اختبار واجهة برمجة التطبيقات هذه. لنفعلها اذا!

مثال: تغيير النص عند تغيير حجم عنصر


تخيل الموقف التالي - يجب أن يتغير النص داخل العنصر اعتمادًا على حجم العنصر. يوفر ResizeObserver API أداتين - ResizeObserver و ResizeObserverEntry. يتم استخدام ResizeObserver لتتبع حجم عنصر ، ويحتوي ResizeObserverEntry على معلومات حول العنصر الذي تم تغيير حجمه.
الكود بسيط جدا:

<h1> size </h1>
<h2> boring text </h2>

const ro = new ResizeObserver(entries => {
    for(let entry of entries){
        const width = entry.contentBoxSize
        ? entry.contentBoxSize.inlineSize
        : entry.contentRect.width

        if(entry.target.tagName === 'H1'){
            entry.target.textContent = width < 1000 'small' : 'big'
        }

        if(entry.target.tagName === 'H2' && width < 500){
            entry.target.textContent = `I won't change anymore`
            ro.unobserve(entry.target) //  ,     500px
        }
    }
})

//       
ro.observe(document.querySelector('h1'))
ro.observe(document.querySelector('h2'))

أولاً ، أنشئ كائن ResizeObserver وقم بتمرير وظيفة رد الاتصال إليه كمعلمة:

const resizeObserver = new ResizeObserver((entries, observer) => {
    for(let entry of entries){
        // 
    }
})

يتم استدعاء الوظيفة في كل مرة يتم فيها تغيير حجم أحد العناصر الموجودة في ResizeObserverEntries. المعلمة الثانية لوظيفة رد الاتصال هي المراقبة نفسها. يمكننا استخدامه ، على سبيل المثال ، لإيقاف التتبع عند استيفاء شرط معين.

يحصل رد الاتصال على مجموعة من ResizeObserverEntry. يحتوي كل إدخال على أبعاد العنصر المرصود (الهدف).

for(let entry of entries){
    const width = entry.contentBoxSize
    ? entry.contentBoxSize.inlineSize
    : entry.contentRect.width

    if(entry.target.tagName === 'H1'){
        entry.target.textContent = width < 1000 ? 'small' : 'big'
    }
    ...
}

لدينا ثلاث خصائص تصف حجم العنصر - borderBoxSize و contentBoxSize و contentRect. إنها تمثل النموذج المربع للعنصر ، والذي سنتحدث عنه لاحقًا. الآن بضع كلمات حول الدعم. تدعم معظم المتصفحات contentRect ، ومع ذلك ، على ما يبدو ، سيتم إيقاف هذه الخاصية:
ظهر contentRect في مرحلة التطوير الأولية لـ ResizeObserver وتمت إضافته فقط من أجل التوافق الحالي. ربما في المستقبل سيعتبر عفا عليه الزمن.


لذلك ، أوصي بشدة باستخدام contentRect بالتزامن مع bordeBoxSize و contentBoxSize. يتضمن ResizeObserverSize خاصيتين: inlineSize و blockSize ، والتي يمكن تفسيرها على أنها عرض وارتفاع. (بشرط أن نعمل في الاتجاه الأفقي للنص - وضع الكتابة: أفقي).

مراقبة العنصر


آخر شيء فعله هو البدء في تتبع العنصر. للقيام بذلك ، نسمي ResizeObserver.observe (). تضيف هذه الطريقة هدفًا جديدًا إلى قائمة العناصر التي تمت ملاحظتها. يمكننا أن نضيف إلى هذه القائمة إما عنصر واحد أو عدة عناصر في وقت واحد:

// resizeObserver(target, options)
ro.observe(document.querySelector('h1'))
ro.observe(document.querySelector('h2'))

المعلمة الثانية هي "اختياري". حتى الآن ، الخيار الوحيد المتاح هو المربع ، الذي يحدد نموذج كتلة. القيم المحتملة هي مربع المحتوى (افتراضي) ومربع الحدود وجهاز بكسل المحتوى (صندوق Chrome فقط). يمكن تعريف نموذج كتلة واحد فقط في ResizeObserver واحد.

لإيقاف المراقبة ، استخدم ResizeObserver.unobserve (الهدف). لإيقاف تعقب جميع العناصر ، استخدم ResizeObserver.disconnect ().

نموذج كتلة


مربع المحتوى هو محتوى الكتلة دون الحشو والحدود والهامش. يتضمن مربع الحدود المساحة المتروكة والحدود (بدون هامش).



مربع محتوى وحدات بكسل الجهاز هو محتوى العنصر بالبكسل الفعلي. لم أر أمثلة على استخدام هذا النموذج ، ولكن يبدو أن هذا قد يكون مفيدًا عند العمل مع القماش. هنا مناقشة مثيرة للاهتمام حول هذا الموضوع على Github.

متى يكتشف المراقب التغييرات؟


يتم استدعاء رد الاتصال في كل مرة يتم فيها تغيير حجم العنصر الهدف. إليك ما تقوله المواصفات عن ذلك:

  • يتم تشغيل الملاحظة عند إضافة / إزالة عنصر تمت ملاحظته من DOM.
  • يتم تشغيل الملاحظة عند تعيين خاصية العرض للعنصر المرصود على لا شيء.
  • لا تعمل الملاحظة لعناصر الخط "غير المستبدلة".
  • لا تعمل الملاحظة في تحويل CSS.
  • , , .. , 0,0.

وفقًا للفقرة الأولى ، يمكننا تحديد التغيير في الحاوية الرئيسية عند تغيير أطفالها. من الأمثلة الرائعة على استخدام مثل ResizeObserver API التمرير لأسفل نافذة الدردشة عند إضافة رسالة جديدة. يمكن رؤية مثال هنا .

هل تتذكر استفسارات حجم الحاوية التي ذكرتها سابقًا؟ عن مشكلته في الاعتماد الدائري؟ لذا ، فإن ResizeObserver API يحتوي على حل مدمج لمنع تكرار حلقة "تغيير الحجم". اقرأ عنها هنا .

شكرآ لك على أهتمامك.

روابط مفيدة:

مواصفات
MDN
CanIUse
أول مقالة من فريق التطوير
الأكثر شيوعًا

Source: https://habr.com/ru/post/undefined/


All Articles