Вопрос к профи JavaScript о жизнеспособности кода select
Вопрос к профи JavaScript о жизнеспособности кода.
Пользовательский select. полная свобода над тем что и куда вставлять.
Просьба дать обратную связь насколько всё плохо или хорошо).
const nameSelect = "quiz";
const EL = document.querySelector("." + nameSelect + "-select");
const EL_TOGGLE = EL.querySelector("." + nameSelect + "-select__toggle");
const EL_TOGGLE_ALL_EL = EL_TOGGLE.querySelectorAll("*");
const EL_TOGGLE_SELECTED_OPTION = EL_TOGGLE.querySelector("." + nameSelect + "-select__toggle-selected");
const EL_OPTIONS = EL.querySelector("." + nameSelect + "-select__options");
const EL_OPTION = EL_OPTIONS.querySelectorAll("." + nameSelect + "-select__option");
const EL_DROPDOWN = EL.querySelector("." + nameSelect + "-select__dropdown");
let selectOptionValue = "";
let selectOptionIndex = 0;
// Показ скрытие списка
function showHide() {
EL_DROPDOWN.style.display === "block" ?
(EL_DROPDOWN.style.display = "none") :
(EL_DROPDOWN.style.display = "block");
}
// Добавляет событие открытия на все дочерние элементы внутри toggle
// Добавляем атрибут select__toggle_children ко всем дочерним элементам
EL_TOGGLE.addEventListener("click", showHide);
EL_TOGGLE_ALL_EL.forEach(function(event) {
event.addEventListener("click", showHide);
event.setAttribute("select__toggle_children", "1");
});
// Скрывает список с опциями
// Не скрывает список, если кликаем по дочерним элементам
// selectToggle проверяет есть ли у EL_TOGGLE дочерние элементы
document.addEventListener("click", function(event) {
const selectToggle = event.target.getAttribute("select__toggle_children");
if (event.target != EL_TOGGLE && 1 != selectToggle) {
EL_DROPDOWN.style.display = "none";
}
});
// Выбор элементов из списка
EL_OPTIONS.addEventListener("click", function(event) {
// Удалить класс у всех li элементов внутри EL_OPTIONS
EL_OPTION.forEach(function(option, index) {
option.classList.remove(nameSelect + "-select__option-selected");
option.setAttribute("data-index", index);
});
// Добавить класс elect__option_selected к выбранному элементу
event.target.classList.add(nameSelect + "-select__option-selected");
selectOptionValue = event.target.getAttribute("data-value");
selectOptionIndex = event.target.getAttribute("data-index");
// Поднимаем в верх выбранный элемент списка
EL_OPTIONS.insertBefore(event.target, EL_OPTIONS.firstChild);
// Добавить в выбранный элемент списка текст.
EL_TOGGLE_SELECTED_OPTION.innerHTML = event.target.innerHTML;
});
.quiz-select {
position: relative;
}
.quiz-select__toggle {
display: flex;
width: 100%;
height: 56px;
border: 1px solid #383838;
border-radius: 16px;
justify-content: space-between;
align-items: center;
padding: 10px 16px;
}
.quiz-select__toggle::after {
width: 0.75rem;
height: 0.75rem;
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" height="100" width="100"%3E%3Cpath d="M97.625 25.3l-4.813-4.89c-1.668-1.606-3.616-2.41-5.84-2.41-2.27 0-4.194.804-5.777 2.41L50 52.087 18.806 20.412C17.223 18.805 15.298 18 13.03 18c-2.225 0-4.172.804-5.84 2.41l-4.75 4.89C.813 26.95 0 28.927 0 31.23c0 2.346.814 4.301 2.439 5.865l41.784 42.428C45.764 81.174 47.689 82 50 82c2.268 0 4.215-.826 5.84-2.476l41.784-42.428c1.584-1.608 2.376-3.563 2.376-5.865 0-2.26-.792-4.236-2.375-5.932z"/%3E%3C/svg%3E');
background-size: cover;
content: "";
}
.quiz-select__toggle div p {
display: flex;
align-items: start;
}
.quiz-select__toggle div p:first-child {
font-size: 12px;
color: #9b9b9b;
}
.quiz-select__dropdown {
position: absolute;
right: 0;
left: 0;
z-index: 2;
padding: 6px;
display: none;
background: #fff;
box-shadow: 0px 4px 40px rgba(0, 0, 0, 0.08);
border-radius: 16px;
}
.quiz-select__options {
max-height: 160px;
overflow-y: auto;
}
.quiz-select__option {
display: flex;
padding: 0.375rem 0.75rem;
}
.quiz-select__option::before {
flex-shrink: 0;
width: 20px;
height: 20px;
margin-right: 10px;
background-image: url("../img/checked.png");
background-size: cover;
content: "";
}
.quiz-select__option-selected {
display: flex;
align-items: center;
height: 52px;
border-bottom: 1px solid #383838;
}
.quiz-select__option-selected::before {
background-position-x: 100%;
content: "";
}
.quiz-select__option:hover {
background-color: #f5f5f5;
cursor: pointer;
transition: 0.2s background-color ease-in-out;
}
/* Работает в Firefox */
* {
scrollbar-width: thin;
scrollbar-color: #d8d8d8;
}
/* Работает в Chrome, Edge и Safari */
*::-webkit-scrollbar {
width: 4px;
}
*::-webkit-scrollbar-thumb {
background-color: #d8d8d8;
border-radius: 20px;
width: 4px;
}
<div class="quiz-select">
<button type="button" class="quiz-select__toggle">
<div>
<p>Машина</p>
<p class="quiz-select__toggle-selected">Выберите из списка</p>
</div>
</button>
<div class="quiz-select__dropdown">
<ul class="quiz-select__options">
<li class="quiz-select__option quiz-select__option-selected" data-value="volkswagen" data-index="">Volkswagen</li>
<li class="quiz-select__option" data-value="ford" data-index="">Ford</li>
<li class="quiz-select__option" data-value="toyota" data-index="">Toyota</li>
<li class="quiz-select__option" data-value="ford" data-index="">Ford</li>
<li class="quiz-select__option" data-value="toyota" data-index="">Toyota</li>
<li class="quiz-select__option" data-value="ford" data-index="">Ford</li>
<li class="quiz-select__option" data-value="toyota" data-index="">Toyota</li>
<li class="quiz-select__option" data-value="ford" data-index="">Ford</li>
<li class="quiz-select__option" data-value="toyota" data-index="">Toyota</li>
</ul>
</div>
</div>
Источник: Stack Overflow на русском