Знаете ли дека чувството кога создавате сопствена компонента наместо да ги подобрувате HTML компонентите? Вашиот дизајнерски тим создаде нешто убаво, но прелистувачите нема да го поддржат надвор од кутијата, а поправањето насекаде станува кошмар.
Денес, сакав да зборувам за една стапица што нè очекува за време на ова возбудливо патување: поставувањето на елементи за спуштање, како што се избраните менија или селекторите за датуми.
Апсолутно погрешно
На почетокот изгледа како position: absolute
ги решава сите наши проблеми, и тоа го прави до одреден степен.позиција: апсолутно
Тоа е далеку од совршено – можеме да направиме подобро.
Fix It со 'fixed'
'фиксен'
Ако сакаме да ја прикажеме содржината над сè, ни треба position: fixed
. Единствениот проблем е што ќе ги изгубиме координатите на родителскиот елемент: фиксните елементи се сосема независни по природа.позиција: фиксна
- Кога ја прикажуваме.
- Кога се менува нејзината содржина.
- Кога се поместува прозорецот и/или ролетниот родител.
- Кога се менува големината на прозорецот и/или ролетниот родител.
Ние исто така треба да одлучиме дали да го прикажеме над приклучокот ако е премногу близу до дното на екранот.
Јас ќе го користам Vue.js, но тоа треба да биде лесно да се следи дури и ако сакате React или Angular.
Let’s Rock This Joint
Погледнете го видеотоОвде е структурата што ќе ја користиме:
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: HTMLE TITLE null = null, dropdownElement: HTMLDivementElement null = null, dropdownContent: Ref<nunkexport 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 = (is DropdownDisplayed: Ref<boolean>, togglerElement: HTMLE tiger null = null, dropdownElement: HTMLDivementEl tiger null = null, dropdownContent: Ref<nunkown>Постојат четири променливи за положбата на паѓање, плус знамето isDirectedUpwards
и функција која ги ажурира сите нив.isDirectedUpwards
Напред
Како што можеби се сеќавате, ние исто така треба да се справиме со прелистувањето и прелистувањето на прелистувачот, па да креираме функција за да ја најдеме:
const getFirstScrollableParent = (елемент: HTMLElementintza null): HTMLElement => { const parentElement = element?.parentElement; ако (!parentElement) вратите document.body; const overflowY = window.getComputedStyle(parentElement).overflowY; ако (overflowY ==='scroll' Átha overflowY === 'auto') вратите parentElement; return getFirstScrollableParent(parentElement); };
const getFirstScrollableParent = (element: HTMLElementannoo null): HTMLElement => { const parentElement = element?.parentElement; if (!parentElement) return document.body; const overflowY = window.getComputedStyle(parentElement).overflowY; if (overflowY ==='scroll' Átha overflowY === 'auto') return parentElement; return getFirstScrollableParent(parentElement); };
Сега, ајде да ја додадеме главната функција:
[Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука] [Одлука]<Кодекс на отпадокот е.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.Т.ТНие поминуваме isDropdownDisplayed
и dropdownContent
за да можеме да реагираме на нивните ажурирања.
isDropdownПогледнете го
DropdownСодржина
Ние исто така помине togglerElement
и dropdownElement
, кои ние треба да се пресмета позицијата.
TogglerЕлемент
DropdownОдлука
На крајот, постои isUpwardPreferred
во случај да сакате да се спушти над toggler по дефолт.
еПредпочитано
Време за релаксација и уживање
Во вашата компонента, ќе ви треба нешто како ова (се претпоставувам дека сте додале рефи во вашиот toggler и dropdown во шаблонот):
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); }
</>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); }
И CSS ќе изгледа вака:
.dropdown { position: fixed; bottom: v-bind('isDirectedUpwards? dropdownBottom : dropdownTop'); left: v-bind('dropdownLeft'); width: v-bind('dropdownWidth'); min-width: 0; }
.dropdown { position: fixed; bottom: v-bind('isDirectedUpwards? dropdownBottom : dropdownTop'); left: v-bind('dropdownLeft'); width: v-bind('dropdownWidth'); min-width: 0; }
Voilà. спуштањето се прикажува правилно дури и кога се преплавува и се движи над превртувачот ако нема доволно простор подолу.
И бидејќи сме на крајот на статијата, би сакал да ви оставам нешто весело - но јас сум надвор од идеи.
Можете да го најдете целосниот код на GitHub.
Можете да го најдете целосниот код на GitHub.GitHub