HTML zapewnia natywny sposób tworzenia pól wyboru, które obsługują wybieranie wielu elementów za pomocą atrybutu multiple na elementach select, ale renderowanie tego naprawdę nie jest zbyt zwarte lub ładne, i nie ma zbyt wiele, co można zrobić stylistycznie z opcjami w polu wyboru. Nie mogłem znaleźć żadnych niestandardowych projektów, które pasowałyby do stylu, którego szukałem, więc skończyło się na stworzeniu własnego. Pełny kod jest dostępny na moim GitHubie tutaj wraz z pasującym paskiem wyszukiwania.
To jest zbudowane od zera z powodu trudności w zmianie zachowania i stylu zwykłego selecta. Normalnie widoczna część selektora jest prostym przyciskiem. Menu rozwijane to div ukryty przez klasę użytkową Bootstrap d-none, z zaokrągleniem i cieniowaniem zastosowanym przez klasy użytkowe Bootstrap shadow i rounded. Opcje są prostymi polami wyboru z etykietami. Mogłyby one zostać zastąpione przyciskami radiowymi, jeśli chciałbyś mieć pasujące pojedyncze pole wyboru.
Tutaj jest końcowy HTML dla przycisku i menu
<div> <button onclick="dropDown(event);" class="menu-btn" type="button"> Menu 1 ⌵ </button> <div class="d-none shadow rounded menu"> <span class="d-block menu-option"><label><input type="checkbox"> Option 1</label></span> <span class="d-block menu-option"><label><input type="checkbox"> Option 2</label></span> <span class="d-block menu-option"><label><input type="checkbox"> Option 3</label></span> </div></div>
Chciałem, aby przycisk menu był zaokrąglony i dość mały, więc odpowiednio go wystylizowałem (możesz oczywiście stylizować w dowolny sposób, nie ma to żadnego wpływu na funkcję):
.menu-btn { border-radius: 48px; border: 0.5px solid lightgrey; font-size: 0.9em; padding: 2px 10px; background-color: white;}
Dla samego menu dodałem trochę paddingu, aby tekst nie najeżdżał na górę menu oraz trochę marginesu, aby nie zachodził na przycisk (oba całkowicie opcjonalne). Dodałem także wysoki z-index (aby wyświetlało się nad innymi rzeczami), kolor tła (domyślnie jest przezroczyste, co wygląda głupio w tym kontekście), i ustawiłem pozycję na absolutną, aby nie spychało innych rzeczy w dół strony.
.menu { padding-top: 10px; z-index: 200; margin-top: 4px; background-color: white; position: absolute;}
Dla opcji menu dodałem trochę paddingu, aby je rozdzielić.
.menu-option { padding: 6px 20px 6px;}
Potrzebujemy sposobu na wykrycie, kiedy kliknięcia są wykonywane poza menu rozwijanym, tak aby można je było opuścić klikając poza nim, jak normalne pole wyboru. Zrobiłem to tworząc div, który pokrywa cały ekran z niższym z-index niż menu. To pozwala nam wykryć wszystkie kliknięcia poza menu
<div class="d-none" onclick="hide(event)"></div>
#overlay { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; z-index: 100;}
Aby to faktycznie działało, potrzebujemy funkcji JavaScript, które sprawią, że menu i nakładka będą się pojawiać i znikać.
Ta funkcja usuwa klasy d-none z menu i nakładki, aktywując je. Zamiast obsługiwać to poprzez ID, po prostu bierze drugi element rodzica celu (przycisku) i zakłada, że to jest menu. To jest powód, dla którego menu i przycisk są zawinięte w pustym div.
function dropDown(event) { event.target.parentElement.children.classList.remove("d-none"); document.getElementById("overlay").classList.remove("d-none");}
Ta funkcja dodaje klasę d-none do nakładki i wszystkich elementów z klasą menu, ukrywając je.
function hide(event) { var items = document.getElementsByClassName('menu'); for (let i = 0; i < items.length; i++) { items.classList.add("d-none"); } document.getElementById("overlay").classList.add("d-none");}
Jeśli uznałeś to za przydatne, być może spodoba Ci się również mój dopasowany projekt paska wyszukiwania.