Γνωρίζετε αυτό το συναίσθημα όταν δημιουργείτε το δικό σας στοιχείο αντί να βελτιώνετε τα προεπιλεγμένα στοιχεία HTML; Η ομάδα σχεδιασμού σας δημιούργησε κάτι όμορφο, αλλά τα προγράμματα περιήγησης δεν θα το υποστηρίξουν έξω από το κουτί, και η επιδιόρθωσή του παντού γίνεται εφιάλτης.
Σήμερα, ήθελα να μιλήσω για μια παγίδα που μας περιμένει κατά τη διάρκεια αυτού του συναρπαστικού ταξιδιού: η τοποθέτηση των στοιχείων dropdown, όπως τα επιλεγμένα μενού ή οι επιλογές ημερομηνίας.
Απολύτως λάθος
Στην αρχή, μοιάζει με position: το απόλυτο
λύνει όλα τα προβλήματα μας, και το κάνει σε κάποιο βαθμό.θέση: απόλυτη
Αυτό απέχει πολύ από το να είναι τέλειο – μπορούμε να το κάνουμε καλύτερα.
Fix It With 'fixed'
Κωδικός > Κωδικός > Κωδικός > ΚωδικόςΑν θέλουμε να εμφανίσουμε το περιεχόμενο πάνω από όλα, χρειαζόμαστε position: fixed
. Το μόνο πρόβλημα είναι ότι θα χάσουμε τις συντεταγμένες του γονικού στοιχείου: τα σταθερά στοιχεία είναι αρκετά ανεξάρτητα από τη φύση τους.Κωδικός > Κωδικός > Κωδικός > Κωδικός
- Όταν το εμφανίζουμε.
- Όταν αλλάζει το περιεχόμενό του.
- Όταν κάνουμε κύλιση του παραθύρου και/ή του κυλιόμενου γονέα.
- Όταν αλλάζουμε το μέγεθος του παραθύρου και/ή του κυλιόμενου γονέα.
Χρειάζεται επίσης να αποφασίσουμε αν θα το εμφανίσουμε πάνω από το toggler αν είναι πολύ κοντά στο κάτω μέρος της οθόνης.
Θα χρησιμοποιήσω το 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 Echelon 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 = (isDropdownDisplayed: Ref<boolean>, togglerElement: HTMLE tiger null = null, dropdownElement: HTMLDivementEl tiger null = null, dropdownContent: Ref<nunkown>Υπάρχουν τέσσερις μεταβλητές για τη θέση πτώσης συν τη σημαία isDirectedUpwards
και μια συνάρτηση που τις ενημερώνει όλες.Κωδικός isDirectedUpwards
Όπως μπορεί να θυμάστε, πρέπει επίσης να χειριστούμε την κύλιση και την αλλαγή της κύλισης του κύλισης γονέα, οπότε ας δημιουργήσουμε μια συνάρτηση για να την βρούμε:
const getFirstScrollableParent = (element: HTMLElementintza null): HTMLElement => { const parentElement = element?.parentElement; αν (!parentElement) επιστρέψετε document.body; const overflowY = window.getComputedStyle(parentElement).overflowY; αν (overflowY ==='scroll' Átha overflowY === 'auto') επιστρέψετε parentElement; επιστρέψτε getFirstScrollableParent(parentElement); };
const getFirstScrollableParent = (element: HTMLElementannoo null): HTMLElement => { const parentElement = element?.parentElement; αν (!parentElement) επιστρέψετε document.body; const overflowY = window.getComputedStyle(parentElement).overflowY; αν (overflowY ==='scroll' Doue overflowY === 'auto') επιστρέψετε parentElement; επιστρέψτε getFirstScrollableParent(parentElement); };
Τώρα, ας προσθέσουμε την κύρια συνάρτηση:
Ύψος Ύψος Ύψος Ύψος Ύψος Ύψος Ύψος Ύψος Ύψος Ύψος Ύψος Ύψος Ύψος Ύψος Ύψος Ύψος ΎψοςΕτικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: Ετικέτες: ΕτικέΔιαβιβάζουμε το isDropdownDisplayed
και το dropdownContent
για να μπορέσουμε να αντιδράσουμε στις ενημερώσεις τους.
isDropdownΕμφάνιση
DropdownΠεριεχόμενο
Περνάμε επίσης το togglerElement
και το dropdownElement
το οποίο χρειάζεται για να υπολογίσουμε τη θέση.
TogglerΤο στοιχείο
DropdownΤο στοιχείο
Τελικά, υπάρχει το isUpwardPreferred
σε περίπτωση που θέλετε το dropdown πάνω από το toggler από προεπιλογή.
Κωδικός προτιμάται
Χρόνος για να χαλαρώσετε και να απολαύσετε
Στο στοιχείο σας, θα χρειαστείτε κάτι σαν αυτό (υποθέτω ότι έχετε προσθέσει refs στο 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 { θέση: σταθερή· κάτω: v-bind('isDirectedUpwards? dropdownBottom : dropdownTop'); αριστερά: v-bind('dropdownLeft'); πλάτος: v-bind('dropdownWidth'); min-width: 0; }
.dropdown { θέση: σταθερή· κάτω: v-bind('isDirectedUpwards? dropdownBottom : dropdownTop'); αριστερά: v-bind('dropdownLeft'); πλάτος: v-bind('dropdownWidth'); min-width: 0; }
Η πτώση εμφανίζεται σωστά ακόμη και κατά τη διάρκεια της υπερφόρτωσης και κινείται πάνω από τον διακόπτη εάν δεν υπάρχει αρκετός χώρος κάτω.
Και δεδομένου ότι είμαστε στο τέλος του άρθρου, θα ήθελα να σας αφήσω με κάτι χαρούμενο - αλλά δεν έχω ιδέες.
Μπορείτε να βρείτε τον πλήρη κώδικα στο GitHub.
Μπορείτε να βρείτε τον πλήρη κώδικα στο GitHub.GitHub