Имитация select с помощью ul списка. Работает, но из-за зацикливания кода страница виснет

Нужен был вот такой красивый кастомизированный как бы select.

неактивный селект

Активное состояние селекта

Сделать получилось ненумерованным списком.

(function () {
  const select = document.querySelector('.offers__pseudo-select');
  const option = document.querySelectorAll('.offers__pseudo-option');

  if (select, option) {

    const actionSelect = () => {
      option.forEach((element) => {
        element.addEventListener('click', () => {
          select.classList.add('offers__pseudo-select--active');
          option.forEach((elt) => {
            elt.classList.add('offers__pseudo-option--active');
            elt.addEventListener('click', () => {
              option.forEach((el) => {
                el.classList.remove('offers__pseudo-option--active');
                elt.classList.add('offers__pseudo-option--active');
                select.classList.remove('offers__pseudo-select--active');
                actionSelect();
              });
            }, { once: true });
          });
        }, { once: true });

      });
    };
    actionSelect();
  }
}());
.offers__pseudo-select {
  width: 174px;
  height: 35px;
  background: #ffffff;
  box-shadow: 0px 2px 12px rgba(173, 152, 143, 0.18);
  border: 1px solid rgba(173, 152, 143, 0.18);
  border-radius: 25px;
  padding: 0 15px 0 30px;
  box-sizing: border-box;
  margin: 0;
  list-style-type: none;
  outline: none;

  &::after {
    @include pseudo;
    width: 17px;
    height: 10px;
    background: url('../img/icons/select-main-triangle-black-down.svg') no-repeat;
    top: 14px;
    right: 13px;
  }
}

.offers__pseudo-select--active {
  height: max-content;
  border-radius: 0;
  position: absolute;
  top: -17px;
  left: -173px;
  z-index: 1;
}

.offers__pseudo-option {
  display: none;
  position: relative;
  margin: 7px 0 0 5px;
  z-index: 1000;
}

.offers__pseudo-option--active {
  display: block;
}

.offers__pseudo-option-1::after,
.offers__pseudo-option-3::after {
  @include pseudo;
  width: 11px;
  height: 10px;
  background: url("../img/icons/arrow-select.svg") no-repeat;
  top: 4px;
  left: -13px;
}

.offers__pseudo-option-2::after,
.offers__pseudo-option-4::after {
  @include pseudo;
  width: 7px;
  height: 11px;
  background: url("../img/icons/arrow-select.svg") no-repeat;
  top: 4px;
  left: -13px;
  transform: rotate(180deg);
}
 <div class="offers__filter-select">
              <ul class="offers__pseudo-select">
                <li class="offers__pseudo-option offers__pseudo-option-1 offers__pseudo-option--active" tabindex="0">По площади</li>
                <li class="offers__pseudo-option offers__pseudo-option-2" tabindex="0">По площади</li>
                <li class="offers__pseudo-option offers__pseudo-option-3" tabindex="0">По цене</li>
                <li class="offers__pseudo-option offers__pseudo-option-4" tabindex="0">По цене</li>
              </ul>
            </div>

Проблема в моём слабом знании JS: чтобы функция, обеспечивающая работу этого псевдоселекта срабатывала больше одного раза, я ее перезапускаю изнутри, что, наверное, идиотизм. После нескольких успешных срабатываний страница виснет. То ли наслоение обработчиков событий происходит, то ли перезапускающаяся функция сжирает память. Базовых знаний не хватает...


Ответы (1 шт):

Автор решения: Проста Miha

const sort = document.querySelector(".sort");
const sortOptions = document.querySelector(".sort-list");
const sortDefault = document.querySelector(".sort-default");

for (let i = 0; i < sortOptions.children.length; i++) {
  sortOptions.children[i].addEventListener("click", function() {
    sortDefault.innerHTML = this.innerHTML;
  })
}

sort.addEventListener("click", function() {
  this.children[1].classList.toggle("sort-active");
})
* {
  box-sizing: border-box;
}

.center {
  display: inline-block;
}

.center ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  display: none;
}

.center ul li,
.center>div {
  position: relative;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  cursor: pointer;
}

.sort-list li {
  padding: 8px 0;
  border-top: 1px solid #000;
}

.sort-list li:hover {
  color: red;
}

.sort-active {
  display: inline-block !important;
}

</style>
<div class="center sort">
  <div class="sort-default"><img src="https://img.icons8.com/ios/20/000000/up--v1.png" />Что-то вверх 1</div>
  <ul class="sort-list">
    <li><img src="https://img.icons8.com/ios/20/000000/up--v1.png" />Что-то вверх 1</li>
    <li><img src="https://img.icons8.com/ios/20/000000/down--v1.png" />Что-то вниз 1</li>
    <li><img src="https://img.icons8.com/ios/20/000000/up--v1.png" />Что-то вверх 2</li>
    <li><img src="https://img.icons8.com/ios/20/000000/down--v1.png" />Что-то вниз 2</li>
  </ul>
</div>

→ Ссылка