جعل جدول التمرير لانهائي دون مستمع الحدث

لماذا يتخلف ذلك؟



إذا كان عند تقديم طاولة ضخمة مع نوع من الرسوم المتحركة الانتقالية ، فلن يتم تنفيذ أي شيء آخر ، فسيخلف التطبيق ، وسيعاني المستخدم.




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


الكود سيكون شيء مثل هذا:


 componentDidMount() { window.addEventListener('scroll', this.handleScroll) } handleScroll(e) { // use window offset and boundingRect const { ...someAttributes } = window; const { ...someBoundingRect } = this.component // some logic prevent re-render if ( ... ) return; // do some math const newIndex = ... // and how many rows should be rendered this.setState({index: newIndex }) } 

ولكن هناك طريقة أخرى لتطبيق التمرير اللانهائي لجدول ، دون معرفة أي شيء عن قيم النافذة أو قيم الإلحاق.


هذا هو IntersectionObserver . التعريف من w3c :


توضح هذه المواصفة API التي يمكن استخدامها لمعرفة مدى رؤية عناصر DOM وموضعها ("الأهداف") بالنسبة للعناصر الموجودة فيها.

عند استخدام هذه الطريقة ، لن تحتاج إلى معرفة ارتفاع السطر أو أعلى إطار العرض أو أي قيمة أخرى للقيام بالرياضيات.



يتمثل المفهوم في ترتيب نقاط الارتساء مع مؤشرات في كل نقطة تحكم وفي كل مرة يتم فيها تشغيل المرساة ، احصل على قيمة المؤشر وأعد رسم الجدول. بفضل هذا ، لا تحتاج إلى القيام بأي سحر رياضي مع ارتفاع DOM و viewport.



مرساة الزناد للمؤشر 1


تقديم المزيد من الخطوط


سيكون رمز مع IntersectionObserver شيء مثل هذا.



 handleSentinel = (c) => { if(!this.observer) { //  observer this.observer = new IntersectionObserver( entries => { entries.forEach(e => { //   ,    if (e.isIntersecting) { this.setState( { cursor: +e.target.getAttribute('index') } ); } }); }, { root: document.querySelector('App'), rootMargin: '-30px', } } if (!c) return; //    this.observer.observe(c) } render() { const blockNum = 5; return( ... <tbody> {MOCK_DATA.slice(0, (cursor+1) * blockNum).map(d => <Block> { //       // ,   5  d.id % blockNum === 0 ? <span ref={this.handleSentinel} index={d.id / blockNum} /> : null } </Block>)} </tbody> ... ) } 

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


All Articles