@julith

Как переключить подсветку на следующий элемент списка при нажатии стрелок вверх-вниз?

Пытаюсь настроить событие которое будет распознавать клик стрелочками вверх-вниз и переключать подсветку с Local Disk (C:) на Disk (D:) и (E:). Как это реализовать? По идее в цикле перебираются li с классом parent, и у того, который должен быть подсвечен добавляется к классу пометка active. А как переключать, если стрелка вверх нажимается?

<div>This PC
    <ul class="list" id="list">
        <li class="parent active">Local Dick(C:)
            <ul>
                <li>Programm Files</li>
                <li>Users</li>
                <li>Windows</li>
            </ul>
        </li>
        <li class="parent">Local Dick(D:)
            <ul>
                <li>New Folder 1</li>
                <li>New Folder 2</li>
                <li>New Folder 3</li>
            </ul>
        </li>
        <li class="parent">Local Dick(E:)
            <ul>
                <li>Games
                    <ul>
                        <li>GTA</li>
                        <li>Assasin's creed</li>
                        <li>Skyrim</li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>    
</div>

for (let li of list.querySelectorAll("li")) {
    let span = document.createElement("span"); //создает пространство для клика
    span.classList.add("show");
    li.prepend(span);
    span.append(span.nextSibling);
}

list.onclick = function (event) {
    if (event.target.tagName != "SPAN") return;

    let childrenList = event.target.parentNode.querySelector("ul");

    if (!childrenList) return;
    childrenList.hidden = !childrenList.hidden;

    if (childrenList.hidden) {
        event.target.classList.add("hide");
        event.target.classList.remove("show");
    } else {
        event.target.classList.add("show");
        event.target.classList.remove("hide");
    }
    
};


//подсветка
const parentLi = list.getElementsByClassName('parent');

for(var i = 0; i < parentLi.length; i++) {
    light(parentLi[i].firstChild)
}

function light(parentLi) {
    parentLi.addEventListener('mouseover', function() {
        this.style.color = 'pink';
        this.style.backgroundColor = 'grey';
    })
    parentLi.addEventListener('mouseout', function() {
        this.style.color = 'black';
        this.style.backgroundColor = 'white';
    })
}

//задание 4
//автоматическое переключение при клике
list.addEventListener('keydown', function(parentLi) {
    for (var i = 0; i < parentLi.length; i++) { 
        light(parentLi[i].firstChild); //подсветка 1го элемента
        if (parentLi[i].classList.contains('active')) {
            parentLi[i].classList.remove('active'); //удаляем пометку для подсветки 1го элемента
        }
    }
    parentLi[i].classList.add('active'); //добавляем пометку для следующего эл-та
});
  • Вопрос задан
  • 159 просмотров
Пригласить эксперта
Ответы на вопрос 2
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
Ну для начала, вот сюда:
list.addEventListener('keydown', function(parentLi) {
параметром придет KeyboardEvent, в котором есть данные о нажатых клавишах.

По идее в цикле перебираются li с классом parent, и у того, который должен быть подсвечен добавляется к классу пометка active
Хранить состояние во view слое очень плохая идея. Запоминайте индекс выделенного элемента в переменной и по событию проверяйте возможность переключения подсветки и меняйте классы.

Ну и так, замечание:
for(var i = 0; i < parentLi.length; i++) {
    light(parentLi[i].firstChild)
}

function light(parentLi) {
    parentLi.addEventListener('mouseover', function() {
        this.style.color = 'pink';
        this.style.backgroundColor = 'grey';
    })
    parentLi.addEventListener('mouseout', function() {
        this.style.color = 'black';
        this.style.backgroundColor = 'white';
    })
}
вот тут в цикле создается целая пачка однотипных функций, каждая из которых будет жрать память пользователя. Притом эта задача вообще легко решается на чистом CSS через hover.
Ответ написан
0xD34F
@0xD34F Куратор тега JavaScript
const listEl = document.querySelector('#list');
const activeClass = 'active';
let index = 0;

next(0);

document.addEventListener('keydown', function(e) {
  const step = ({
    ArrowDown: 1,
    ArrowUp: -1,
  })[e.key];

  if (step) {
    next(step);
  }
});

function next(step) {
  const elems = listEl.children;
  elems[index].classList.remove(activeClass);
  index = Math.max(0, Math.min(elems.length - 1, index + step));
  // или, если надо, чтобы при переходе от последнего к следующему элементу
  // активным становился первый, а при переходе от первого к предыдущему
  // активным становился последний
  // index = (index + step + elems.length) % elems.length;
  elems[index].classList.add(activeClass);
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы