سیناریۆکە نزیکەی هەمیشە وەک یەکە، کە خشتەی داتایە لە ناو کۆنتێنەرێکی سکڕۆڵکراودا. هەموو ڕیزێک مینیویەکی کرداری هەیە، دابەزینێکی بچووک لەگەڵ هەندێک بژاردە، وەک دەستکاریکردن، دووبارەکردنەوە و سڕینەوە. تۆ دروستی دەکەیت، پێدەچێت بە شێوەیەکی تەواو لە گۆشەگیریدا کار بکات، دواتر کەسێک دەیخاتە ناو ئەو div سکڕۆڵە و شتەکان لەیەک دەچن. من ئەم هەڵەیەم بە تەواوی لە سێ بنکەی کۆدی جیاوازدا بینیوە: کۆنتێنەر، ستاک و چوارچێوەکە، هەموویان جیاوازن. بەڵام بەگەکە بە تەواوی هاوشێوەیە. دابەزینەکە لە لێواری دەفرەکەدا دەبڕدرێت. یان لە پشت ناوەڕۆکەوە دەردەکەوێت کە بە شێوەیەکی لۆژیکی دەبێ لە خوارەوە بێت. یان بە باشی کاردەکات تا بەکارهێنەرەکە سکڕۆڵ دەکات، و دواتر دەڕوات. دەستت دەگاتە z-index: 9999. هەندێک جار یارمەتیدەرە، بەڵام هەندێکی تر بە هیچ شێوەیەک هیچ ناکات. ئەو ناتەباییە یەکەم ئاماژەیە کە شتێکی قووڵتر ڕوودەدات. هۆکاری ئەوەی کە بەردەوام دەگەڕێتەوە ئەوەیە کە سێ سیستەمی وێبگەڕی جیاواز بەشدارن و زۆربەی گەشەپێدەران بە تەنیا لە هەریەکەیان تێدەگەن بەڵام هەرگیز بیر لەوە ناکەنەوە کە چی ڕوودەدات کاتێک هەر سێیان بەریەکدەکەون: ڕژان، کۆکردنەوەی کۆنتێکستەکان و لەخۆگرتنی بلۆکەکان.
کاتێک تێگەیشتیت کە هەر سێیان چۆن کارلێک دەکەن، شێوازەکانی شکست هەستکردن بە هەڕەمەکی وەستان. لە ڕاستیدا دەبنە شتێکی پێشبینیکراو. ئەو سێ شتەی کە لە ڕاستیدا هۆکاری ئەمەن با بە وردی سەیری هەریەک لەو بابەتانە بکەین. کێشەی سەرڕێژبوون کاتێک کە overflow: hidden، overflow: scroll، یان overflow: auto لەسەر توخمێک دادەنێیت، وێبگەڕەکە هەر شتێک کە لە سنوورەکانی خۆی زیاتر درێژ دەبێتەوە، بە نەوەکانیشەوە کە بە تەواوی جێگیرکراون، دەبڕێت. .scroll-container { ڕژان: ئۆتۆماتیکی؛ بەرزی: 300px؛ /* بەم شێوەیە درۆپ داونەکە کلیپ دەکات، فول ستۆپ */ }
.dropdown { . پێگە: ڕەها؛ /* گرنگ نییە -- هێشتا لەلایەن .scroll-containerەوە بڕاوە */ }
ئەوە یەکەم جار کە تووشی بووم، سەرسامی کردم. من هەڵوێستم وەرگرتبوو: ڕەها ڕێگە بە توخمێک دەدات لە بڕینی دەفرێک ڕزگاری بێت. نایکات. بە کردەوە، ئەوە بەو مانایەیە کە مینیویەکی جێگیرکراوی ڕەها دەتوانرێت لەلایەن هەر باپیرێکەوە ببڕدرێت کە بەهای ڕژانی نابینراوی هەبێت، تەنانەت ئەگەر ئەو باپیرە بلۆکی تێدایە کە مینیوەکە نەبێت. بڕین و جێگیرکردن سیستەمی جیاوازن. تەنها بەڕێکەوت بە شێوەیەک بەریەکدەکەون کە بە تەواوی بە شێوەیەکی هەڕەمەکی دەردەکەون تاوەکو لە هەردووکیان تێدەگەیت.
لێرەدا نموونەیەکی React بە بەکارهێنانی createPortal:
هاوردەکردنی { createPortal } لە 'react-dom'؛ import { useState, useEffect, useRef } لە 'کاردانەوە'؛
function Dropdown({ anchorRef, isOpen, منداڵان }) { const [شوێن، setPosition] = useState ({ سەرەوە: 0، چەپ: 0 });
کاریگەری بەکارهێنان (() => { ئەگەر (isOpen && anchorRef.current) { const rect = anchorRef.current.getBoundingClientRect (); شوێنی دانان({ سەرەوە: rect.bottom + window.scrollY، چەپ: rect.left + window.scrollX، }); } }، [isOpen، anchorRef]);
ئەگەر (!isOpen) گەڕانەوەی null؛
گەڕانەوەی createPortal(
و بێگومان ناتوانین دەستڕاگەیشتن پشتگوێ بخەین. ئەو توخمە جێگیرانەی کە لەسەر ناوەڕۆک دەردەکەون، هێشتا دەبێت بتوانرێت بە کیبۆرد بگات. ئەگەر ڕێزبەندی فۆکەس بە شێوەیەکی سروشتی نەچێتە ناو دابەزینی جێگیرەوە، پێویستە بە بەکارهێنانی کۆد بەڕێوەی بەریت. هەروەها شایەنی ئەوەیە بزانرێت کە لەسەر ناوەڕۆکی کارلێککاری تر دانانیشێت و هیچ ڕێگەیەکی نییە بۆ ڕەتکردنەوەی. ئەو یەکە لە تاقیکردنەوەی کیبۆرددا گازت لێدەگرێت. CSS Anchor Positioning: پێموایە ئەمە بەرەو کوێ دەڕوات CSS Anchor Positioning ئەو ئاراستەیەیە کە لە ئێستادا زۆرترین حەزم لێیە. من دڵنیا نەبووم کە چەندە لە تایبەتمەندییەکان لە ڕاستیدا دەتوانرێت بەکاربهێنرێت کاتێک بۆ یەکەمجار سەیریم کرد. ڕێگەت پێدەدات پەیوەندی نێوان دابەزینێک و تریگەرەکەی ڕاستەوخۆ لە CSSدا ڕابگەیەنیت، وێبگەڕەکەش مامەڵە لەگەڵ کۆئۆردینیاتەکاندا دەکات. .تریگەر { ناوی-لەنگەری: --my-trigger; }
.dropdown-menu { پێگە: ڕەها؛ position-anchor: --من-دەستپێکەر؛ سەرەوە: لەنگەری (خوارەوە); چەپ: لەنگەری (چەپ)؛ position-try-fallbacks: فلیپ-بلۆک، فلیپ-ئینلاین؛ }
تایبەتمەندی position-try-fallbacks ئەوەیە کە ئەمە شایەنی بەکارهێنان بێت لەسەر حیساباتی دەستی. وێبگەڕەکە پێش ئەوەی وازی لێبهێنێت، جێگیرکردنی بەدیل تاقیدەکاتەوە، بۆیە دابەزینێک لە خوارەوەی دەرچەی بینینەکە بە شێوەیەکی ئۆتۆماتیکی بەرەو سەرەوە دەگەڕێتەوە لەبری ئەوەی ببڕدرێت. پشتگیری وێبگەڕ لە وێبگەڕە بنچینەییەکانی کرۆمدا پتەوە و لە سەفاریدا گەشە دەکات. فایەرفۆکس پێویستی بە پۆلیفیڵ هەیە. پاکێجی @oddbird/css-anchor-positioning تایبەتمەندی سەرەکی دەگرێتەوە. من کەیسی لێواری نەخشەم پێ داوە کە پێویستی بە کەوتنەخوارەوە هەبوو کە پێشبینیم نەدەکرد، بۆیە وەک بەرزکردنەوەیەکی پێشکەوتوو مامەڵەی لەگەڵ بکە یان لەگەڵ aفاڵباکی جاڤاسکڕێپت بۆ فایەرفۆکس. بە کورتی بەڵێندەر بەڵام هێشتا گشتگیر نییە. لە وێبگەڕە ئامانجدارەکانتدا تاقی بکەرەوە. وە تا ئەو شوێنەی کە پەیوەندی بە دەستڕاگەیشتنەوە هەیە، ڕاگەیاندنی پەیوەندییەکی بینراو لە CSS هیچ شتێک بە درەختی دەستڕاگەیشتن ناڵێت. aria-controls، aria-expanded، aria-haspopup — ئەو بەشە هێشتا لەسەر تۆیە. هەندێک جار چاککردنەوەکە تەنها جوڵاندنی توخمەکەیە پێش ئەوەی دەستم بۆ پۆرتاڵێک بگات یان حیساباتی کۆئۆردینیات بکەم، هەمیشە سەرەتا یەک پرسیار دەکەم: ئایا ئەم دابەزینە لە ڕاستیدا پێویستی بە ژیانە لەناو دەفری سکڕۆڵەکەدا؟ ئەگەر نەبوو، گواستنەوەی مارکاپەکە بۆ پێچەرێکی ئاست بەرزتر کێشەکە بە تەواوی لەناو دەبات، بەبێ جاڤاسکڕێپت و هیچ حیساباتی کۆئۆردینیات. ئەمە هەمیشە ناتوانرێت. ئەگەر دوگمە و دابەزینەکە لە هەمان پێکهاتەدا کۆبکرێنەوە، جوڵاندنی یەکێکیان بەبێ ئەوی دیکە بە واتای بیرکردنەوە لە تەواوی API دێت. بەڵام کاتێک دەتوانیت بیکەیت، هیچ شتێک نییە بۆ چاککردنەوە. کێشەکە تەنها بوونی نییە. ئەوەی کە سی ئێس ئێسی مۆدێرن هێشتا چارەسەری ناکات CSS لێرەدا ڕێگایەکی دووری بڕیوە، بەڵام هێشتا شوێنێک هەیە کە بێهیوات دەکات. هەڵوێستەکە: کێشەکانی چارەسەرکردن و گۆڕینی هێشتا هەر ماون. بە مەبەست لە تایبەتمەندییەکەدایە، ئەمەش واتە هیچ چارەسەرێکی CSS بوونی نییە. ئەگەر کتێبخانەی ئەنیمەیشن بەکاردەهێنیت کە نەخشەکەت لە توخمێکی گۆڕاودا دەپێچێتەوە، ئەوا گەڕایتەوە بۆ پێویستی پۆرتاڵ یان شوێنی ئەنکر. CSS Anchor Positioning بەڵێندەرە، بەڵام نوێیە. وەک پێشتر باسمان کرد، فایەرفۆکس هێشتا پێویستی بە پۆلیفیڵ هەیە لەو کاتەی کە ئەمە دەنووسم. من لەگەڵیدا کەیسی لێواری نەخشەم لێداوە کە پێویستی بە کەوتنەخوارەوە هەبوو کە پێشبینیم نەدەکرد. ئەگەر ئەمڕۆ پێویستت بە ڕەفتاری بەردەوام هەیە لە سەرانسەری هەموو وێبگەڕەکاندا، تۆ هێشتا دەستت بۆ جاڤاسکڕێپت دەبەیت بۆ بەشە فێڵبازەکان. ئەو زیادکردنەی کە لە ڕاستیدا کاری خۆمم بۆ گۆڕیوە HTML Popover API ە، ئێستا لە هەموو وێبگەڕە مۆدێرنەکاندا بەردەستە. ئەو توخمانەی کە تایبەتمەندی popover یان هەیە لە چینە سەرەوەی وێبگەڕەکەدا ڕەندەر دەکەن، لە سەرووی هەموو شتێکەوە، بەبێ ئەوەی پێویست بە شوێنی جاڤاسکڕێپت بکات.
مامەڵەکردن لەگەڵ هەڵهاتن، دەرکردن لەسەر کلیککردن لە دەرەوە، و ماناسازی دەستگەیشتن بە تۆکمە بەخۆڕایی بۆ شتەکانی وەک ئامۆژگاری ئامرازەکان، ویجتەکانی ئاشکراکردن و سەرپۆشە سادەکان. ئەوە یەکەم ئامرازە کە دەستم پێدەگات بۆ ئێستا. کە ووتمان، ئەوە چارەسەری پێگەیشتن ناکات. چین چینکردن چارەسەر دەکات. هێشتا پێویستت بە جێگیرکردنی ئەنکر یان جاڤاسکڕێپت هەیە بۆ ڕێکخستنی پۆپۆڤەرێک لەگەڵ تریگەرەکەی. API ی Popover مامەڵە لەگەڵ چینکردنەکەدا دەکات. جێگیرکردنی ئەنکر مامەڵە لەگەڵ دانانەکەدا دەکات. پێکەوە بەکاردەهێنرێن، زۆربەی ئەو کارانە دەگرێتەوە کە پێشتر دەستت پێدەگەیشت بۆ کتێبخانەیەک بۆ ئەوەی بیکات. ڕێنمایی بڕیاردان بۆ بارودۆخەکەت دوای ئەوەی بە ڕێگای سەختدا بە هەموو ئەمانەدا تێپەڕیم، لێرەدا لە ڕاستیدا چۆن بیر لە هەڵبژاردنەکە دەکەمەوە ئێستا.
پۆرتاڵێک بەکاربهێنە. من ئەمە بەکاردەهێنم کاتێک کە تریگەرەکە لە قووڵایی دەفرەکانی سکڕۆڵی هێلانەدا دەژی. ئەم نەخشەم بۆ مینیوەکانی کردارەکانی خشتەکان بەکارهێنا و لەگەڵ گەڕاندنەوەی فۆکەس و پشکنینی دەستڕاگەیشتن جووتم کرد. جێی متمانەترین بژاردەیە، بەڵام بودجەی کات بۆ وایەرکردنی زیادە. جێگیرکردنی جێگیر بەکاربهێنە. ئەمە بۆ ئەو کاتەیە کە تۆ لە ڤانێلا جاڤاسکڕێپت یان چوارچێوەیەکی سووکدایت و دەتوانیت پشتڕاستی بکەیتەوە کە هیچ باپیرێک گۆڕانکاری یان فلتەرەکان جێبەجێ ناکات. ڕێکخستنی سادەیە و چاککردنی سادەیە، بە مەرجێک ئەو یەک سنووردارکردنە بەردەوام بێت. CSS Anchor Positioning بەکاربهێنە.دەستپێبکە بۆ ئەمە کاتێک پشتگیری وێبگەڕەکەت ڕێگەی پێدەدات. ئەگەر پشتگیری فایەرفۆکس پێویست بوو، لەگەڵ @oddbird polyfill جووت بکە. ئەمەیە کە پلاتفۆرمەکە لە کۆتاییدا بەرەو ئەوێ دەڕوات و لە کۆتاییدا دەبێتە ڕێگەی ڕۆشتن بۆ تۆ. DOM دابڕێژە. ئەمە بەکاربهێنە کاتێک بیناسازی ڕێگەی پێدەدات، و تۆ دەتەوێت ئاڵۆزی کاتی جێبەجێکردن سفر بێت. من پێم وایە پێدەچێت کەمترین بژاردە بێت. نەخشەکان تێکەڵ بکە. ئەمە بکە کاتێک کە دەتەوێت جێگیرکردنی ئەنکر وەک ڕێگەی سەرەکیت، لەگەڵ کەوتنەخوارەوەی جاڤاسکڕێپت بۆ وێبگەڕە پشتگیری نەکراوەکان جووت کراوە. یان پۆرتاڵێک بۆ دانانی DOM کە لەگەڵ getBoundingClientRect() جووت کراوە بۆ وردی کۆئۆردینیات.
دەرەنجام من پێشتر وەک پرسێکی یەکجارەکی مامەڵەم لەگەڵ ئەم هەڵەیەدا دەکرد — شتێک بۆ ئەوەی چاکی بکەمەوە و لێیەوە بڕۆمە پێشەوە. بەڵام کاتێک لەگەڵیدا دانیشتم بۆ ئەوەی لە هەر سێ سیستەمی بەشداربوو تێبگەم - بڕینی سەرڕێژ، کۆکردنەوەی کۆنتێکستەکان و لەخۆگرتنی بلۆکەکان - هەستکردن بە هەڕەمەکی وەستا. دەمتوانی سەیری دابەزینێکی شکاو بکەم و یەکسەر شوێنپێی بگرم کە کام باپیرە بەرپرسیارە. ئەو گۆڕانکارییە لە چۆنیەتی خوێندنەوەی DOMدا، شتێکی ڕاستەقینەی وەرگرتن بوو. یەک وەڵامی ڕاست نییە. ئەوەی دەستم پێدەگات بەندە بەوەوە کە دەتوانم لە بنکەدراوەی کۆدەکاندا چی کۆنتڕۆڵ بکەم: پۆرتاڵەکان کاتێک درەختی باوباپیران پێشبینی نەکراو بوو؛ جێگیرکردنی جێگیر کاتێک پاک و سادە بوو؛ جوڵاندنی توخمەکە لە کاتێکدا هیچ شتێک ڕێگریم لێ نەدەکرد؛ و جێگیرکردنی لەنگەری ئێستا،لە کوێ دەتوانم. لە کۆتاییدا هەرچییەک هەڵیبژێریت، دەستڕاگەیشتن وەک دوا هەنگاو مامەڵەی لەگەڵ مەکە. بە ئەزموونی من، ڕێک ئەوە کاتێکە کە دەپەڕێتەوە. پەیوەندییەکانی ARIA، بەڕێوەبردنی فۆکەس، هەڵسوکەوتی کیبۆرد — ئەوانە پۆلیش نین. ئەوان بەشێکن لەوەی کە وا دەکات شتەکە لە ڕاستیدا کار بکات. کۆدی سەرچاوەی تەواو لە ڕیپۆی GitHub ـمدا ببینە. خوێندنەوەی زیاتر ئەمانە ئەو ئاماژانەن کە لە کاتی کارکردنمدا لەم ڕێگەیەوە بەردەوام دەگەڕامەوە بۆیان:
کۆنتێکستی کۆکردنەوە (MDN) “ڕێبەری شوێنی لەنگەری CSS”، خوان دیێگۆ ڕۆدریگێز “دەستپێکردن بە API ی پۆپۆڤەر”، گۆدستایم ئابورو UI ی شلۆق (floating-ui.com) CSS Overflow (MDN)