странное поведение js-функции для удаления и добавления класса в mobile, в то время как struncutre в основном тот же

#javascript #html

#javascript #HTML

Вопрос:

По сути, я хочу, чтобы в событии click удалить класс active из текущего элемента и переместить его на выбранный. Я написал следующий код, и в режиме рабочего стола он работает просто отлично, но в мобильной версии он не удаляет класс из «старого активного» элемента, НО если я нажимаю на уже активный элемент, поведение моей функции возвращается к нормальному.

HTML

 <header>
<!-- the ul in the is visible untill 1200px, after that the "mobile-mene" make visibile a hamburger icon and the "menu" is invisible untill the hamburger is clicked -->
    <nav>
        <a href="#home">
            <span class="logo">
                Ernesto Dovizioso
            </span>
        </a>
        <ul>
            <a href="#home"><li class="active">home</li></a>
            <a href="#chisono"><li>chi sono</li></a>
            <a href="#servizi"><li>servizi</li></a>
            <a href="#gallery"><li>galleria</li></a>
            <a href="#contatti"><li>contatti</li></a>
        </ul>
        <div class="mobile-menu">
            <i class="fas fa-bars"></i>
        </div>
    </nav>
    <!-- this is invisible untill the hb menu il clicked -->
    <div class="menu">
        <ul>
            <a href="#home"><li class="active">home</li></a>
            <a href="#chisono"><li>chi sono</li></a>
            <a href="#servizi"><li>servizi</li></a>
            <a href="#gallery"><li>galleria</li></a>
            <a href="#contatti"><li>contatti</li></a>
        </ul>
    </div>
</header>
  

JS

 const ul = document.querySelectorAll("header ul li");
ul.forEach(li => {
    li.addEventListener("click", activeLiChange);
});

function activeLiChange(){
    let activeLi = document.querySelector("li.active");

console.log(this.innerHTML);
console.log(activeLi.innerHTML);

if(!this.isEqualNode(activeLi)){
    this.classList.add("active");
    activeLi.classList.remove("active");
}
  

}

Ответ №1:

Причина, по которой он не работает на мобильном устройстве, заключается в том, что вы используете querySelector which возвращает только первый экземпляр .active , который находится в вашем немобильном меню. Вам нужно будет использовать querySelectorAll('li.active') и перебирать результирующий список узлов.

Использование вашего кода как есть здесь — это исправление:

 const ul = document.querySelectorAll("header ul li");
ul.forEach(li => {
    li.addEventListener("click", activeLiChange);
});

function activeLiChange(){
  const activeLi = document.querySelectorAll("li.active");

  activeLi.forEach(li => {
    if(!this.isEqualNode(li)){
        this.classList.add("active");
        li.classList.remove("active")
    }
  });
}  
 .active {
  color: tomato;
}  
 <header>
  <nav>
        <a href="#home">
            <span class="logo">
                Ernesto Dovizioso
            </span>
        </a>
        <ul>
            <a href="#home"><li class="active">home</li></a>
            <a href="#chisono"><li>chi sono</li></a>
            <a href="#servizi"><li>servizi</li></a>
            <a href="#gallery"><li>galleria</li></a>
            <a href="#contatti"><li>contatti</li></a>
        </ul>
        <div class="mobile-menu">
            <i class="fas fa-bars"></i>
        </div>
    </nav>
    <!-- this is invisible untill the hb menu il clicked -->
    <div class="menu">
        <ul>
            <a href="#home"><li class="active">home</li></a>
            <a href="#chisono"><li>chi sono</li></a>
            <a href="#servizi"><li>servizi</li></a>
            <a href="#gallery"><li>galleria</li></a>
            <a href="#contatti"><li>contatti</li></a>
        </ul>
    </div>
</header>  

Но вы можете упростить это, прикрепив слушателя к каждому ul элементу вместо every li . Затем в вашей activeLiChange() функции используйте target (the li ) и currentTarget (the ul ) для обращения к соответствующему списку меню.

 const ul = document.querySelectorAll("header ul");
ul.forEach(list => {
    list.addEventListener("click", activeLiChange);
});

function activeLiChange(e){
    const activeLi = e.currentTarget.querySelector("li.active");

  if(!e.target.isEqualNode(activeLi)){
    e.target.classList.add("active");
    activeLi.classList.remove("active");
  }
}  
 .active {
  color: tomato;
}  
 <header>
  <nav>
        <a href="#home">
            <span class="logo">
                Ernesto Dovizioso
            </span>
        </a>
        <ul>
            <a href="#home"><li class="active">home</li></a>
            <a href="#chisono"><li>chi sono</li></a>
            <a href="#servizi"><li>servizi</li></a>
            <a href="#gallery"><li>galleria</li></a>
            <a href="#contatti"><li>contatti</li></a>
        </ul>
        <div class="mobile-menu">
            <i class="fas fa-bars"></i>
        </div>
    </nav>
    <!-- this is invisible untill the hb menu il clicked -->
    <div class="menu">
        <ul>
            <a href="#home"><li class="active">home</li></a>
            <a href="#chisono"><li>chi sono</li></a>
            <a href="#servizi"><li>servizi</li></a>
            <a href="#gallery"><li>galleria</li></a>
            <a href="#contatti"><li>contatti</li></a>
        </ul>
    </div>
</header>