کیا آپ اس احساس کو جانتے ہیں جب آپ پہلے سے طے شدہ HTML اجزاء کو بہتر بنانے کے بجائے اپنا جزو بناتے ہیں؟ آپ کی ڈیزائن ٹیم نے کچھ خوبصورت بنایا، لیکن براؤزرز اسے باکس سے باہر سپورٹ نہیں کریں گے، اور اسے ہر جگہ ٹھیک کرنا ایک ڈراؤنا خواب بن جاتا ہے۔ ہم سب اس درد کو جانتے ہیں، لیکن یہ چیلنجز ہمارے کام کو دلچسپ بنا دیتے ہیں۔ آج، میں ایک ایسے نقصان کے بارے میں بات کرنا چاہتا ہوں جو اس سنسنی خیز سفر کے دوران ہمارا انتظار کر رہا ہے: ڈراپ ڈاؤن عناصر کی جگہ کا تعین، جیسے منتخب مینو یا تاریخ چننے والے۔ بالکل غلط سب سے پہلے، یہ ہمارے تمام مسائل کو حل کرتا ہے، اور یہ کسی حد تک کرتا ہے. لیکن پھر، موڈل ونڈوز سب کچھ برباد کر دیتی ہیں۔ position: absolute اگر ڈراپ ڈاؤن اوور فلو ہوتا ہے تو یہ کٹ جاتا ہے۔ یقینی طور پر، آپ نیچے سکرول کر سکتے ہیں اور اسے دیکھ سکتے ہیں، لیکن آپ بہتر یہ دعا کریں گے کہ آپ کا ڈیزائنر کسی تیز چیز کے ساتھ آپ تک نہ پہنچ سکے۔ یہ کامل سے بہت دور ہے - ہم بہتر کر سکتے ہیں۔ اسے کے ساتھ درست کریں 'fixed' اگر ہم مواد کو ہر چیز پر ظاہر کرنا چاہتے ہیں تو ہمیں ۔ صرف مسئلہ یہ ہے کہ ہم بنیادی عنصر کے نقاط کو کھو دیں گے: فکسڈ عناصر فطرت کے لحاظ سے کافی آزاد ہیں۔ اس کا مطلب ہے کہ ہمیں ان حالات میں ڈراپ ڈاؤن عنصر کے صحیح نقاط کا تعین کرنے کی ضرورت ہے: position: fixed جب ہم اسے ظاہر کرتے ہیں۔ جب اس کا مواد تبدیل کیا جاتا ہے۔ جب ہم ونڈو کو اسکرول کرتے ہیں اور/یا سکرول ایبل پیرنٹ۔ جب ہم ونڈو اور/یا سکرول ایبل پیرنٹ کا سائز تبدیل کرتے ہیں۔ ہمیں یہ بھی فیصلہ کرنے کی ضرورت ہے کہ آیا اسے ٹوگلر کے اوپر ڈسپلے کرنا ہے اگر یہ اسکرین کے نیچے کے بہت قریب ہے۔ قابل عمل محسوس ہوتا ہے۔ میں Vue.js استعمال کروں گا، لیکن اس کی پیروی کرنا آسان ہونا چاہیے چاہے آپ React یا Angular کو ترجیح دیں۔ آئیے اس جوائنٹ کو روکیں۔ یہاں وہ ڈھانچہ ہے جسے ہم استعمال کریں گے: export const useDropdownAttributes = () => { const dropdownWidth = ref(''); const dropdownTop = ref(''); const dropdownBottom = ref(''); const dropdownLeft = ref(''); const isDirectedUpwards = ref(false); const togglerRect = ref<DOMRect>(); const dropdownRect = ref<DOMRect>(); const autodetectPosition = ( isDropdownDisplayed: Ref<boolean>, togglerElement: HTMLElement | null = null, dropdownElement: HTMLDivElement | null = null, dropdownContent: Ref<unknown> | ComputedRef<unknown> = ref([]), isUpwardPreferred = false, ) => { // ... } return { autodetectPosition, dropdownTop, dropdownBottom, dropdownLeft, dropdownWidth, isDirectedUpwards, togglerRect, dropdownRect, }; }; ڈراپ ڈاؤن پوزیشن کے علاوہ پرچم اور ایک فنکشن کے لیے چار متغیرات ہیں جو ان سب کو اپ ڈیٹ کرتا ہے۔ ہم ٹوگلرز اور ڈراپ ڈاؤن کے ریکٹس کے لیے بھی دو متغیرات واپس کرتے ہیں: یہ آسان ہو سکتا ہے، مثال کے طور پر، ٹول ٹپس کے لیے جنہیں مواد کے بیچ میں منسلک کرنے کی ضرورت ہے۔ isDirectedUpwards جیسا کہ آپ کو یاد ہوگا۔ const getFirstScrollableParent = (element: HTMLElement | null): HTMLElement => { const parentElement = element?.parentElement; if (!parentElement) return document.body; const overflowY = window.getComputedStyle(parentElement).overflowY; if (overflowY === 'scroll' || overflowY === 'auto') return parentElement; return getFirstScrollableParent(parentElement); }; اب، آئیے مین فنکشن کو شامل کریں: const autodetectPosition = ( isDropdownDisplayed: Ref<boolean>, togglerElement: HTMLElement | null = null, dropdownElement: HTMLElement | null = null, dropdownContent: Ref<unknown> | ComputedRef<unknown> = ref([]), isUpwardPreferred = false, ) => { if (!togglerElement || !dropdownElement) return; const updateDropdownAttributes = () => { togglerRect.value = togglerElement.getBoundingClientRect(); dropdownRect.value = dropdownElement.getBoundingClientRect(); dropdownWidth.value = `${togglerRect.value.width}px`; dropdownBottom.value = `${window.innerHeight - togglerRect.value.top}px`; dropdownTop.value = `${ window.innerHeight - togglerRect.value.bottom - dropdownRect.value.height }px`; dropdownLeft.value = `${togglerRect.value.left}px`; }; const handleResize = () => { requestAnimationFrame(updateDropdownAttributes); }; const handleScroll = () => { requestAnimationFrame(updateDropdownAttributes); }; watch( [isDropdownDisplayed, dropdownContent], ([newVal, _]) => { const scrollableParent = getFirstScrollableParent(togglerElement); if (!newVal) { window.removeEventListener('resize', handleResize); window.removeEventListener('scroll', handleScroll); scrollableParent.removeEventListener('resize', handleResize); scrollableParent.removeEventListener('scroll', handleScroll); return; } requestAnimationFrame(() => { const distanceFromBottom = window.innerHeight - togglerElement.getBoundingClientRect().bottom; const distanceFromTop = togglerElement.getBoundingClientRect().top; const dropdownHeight = dropdownElement.offsetHeight; isDirectedUpwards.value = isUpwardPreferred ? distanceFromTop > dropdownHeight : distanceFromBottom < dropdownHeight && distanceFromTop > dropdownHeight; updateDropdownAttributes(); window.addEventListener('resize', handleResize); window.addEventListener('scroll', handleScroll); scrollableParent.addEventListener('resize', handleResize); scrollableParent.addEventListener('scroll', handleScroll); }); }, { deep: true }, ); }; ہم اور پاس کرتے ہیں تاکہ ہم ان کی تازہ کاریوں پر ردعمل ظاہر کر سکیں۔ isDropdownDisplayed dropdownContent ہم اور بھی پاس کرتے ہیں جس کی ہمیں پوزیشن کا حساب لگانے کی ضرورت ہوتی ہے۔ togglerElement dropdownElement آخر میں، اگر آپ ڈیفالٹ کے طور پر ٹوگلر کے اوپر ڈراپ ڈاؤن چاہتے ہیں تو ہے۔ isUpwardPreferred آرام کرنے اور لطف اٹھانے کا وقت آپ کے اجزاء میں، آپ کو کچھ اس طرح کی ضرورت ہوگی (میرا خیال ہے کہ آپ نے اپنے ٹوگلر اور ٹیمپلیٹ میں ڈراپ ڈاؤن میں ریف شامل کیے ہیں): const { autodetectPosition, dropdownTop, dropdownBottom, dropdownLeft, dropdownWidth, isDirectedUpwards, } = useDropdownAttributes(); const togglerRef = ref<HTMLElement>(); const dropdownRef = ref<HTMLElement>(); const isDropdownShown = ref(false); onMounted(() => { autodetectPosition(isDropdownShown, togglerRef.value?.$el, dropdownRef.value?.$el); }); اور سی ایس ایس اس طرح نظر آئے گا: .dropdown { position: fixed; bottom: v-bind('isDirectedUpwards ? dropdownBottom : dropdownTop'); left: v-bind('dropdownLeft'); width: v-bind('dropdownWidth'); min-width: 0; } Voilà ڈراپ ڈاؤن مناسب طریقے سے ظاہر ہوتا ہے یہاں تک کہ جب بہتا ہوا ہو اور اگر نیچے کافی جگہ نہ ہو تو ٹوگلر کے اوپر چلی جاتی ہے۔ اور چونکہ ہم مضمون کے اختتام پر ہیں، میں آپ کو کچھ خوش گوار چیز کے ساتھ چھوڑنا پسند کروں گا — لیکن میرے خیال سے باہر ہوں۔ لہذا، میں ڈرتا ہوں کہ "گڈ لک" میرے پاس اس وقت ہے. گڈ لک۔ 👋 آپ پر مکمل کوڈ تلاش کر سکتے ہیں۔ GitHub