Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 19.09.2023, 23:28
Новичок на форуме
Отправить личное сообщение для ixiz Посмотреть профиль Найти все сообщения от ixiz
 
Регистрация: 19.09.2023
Сообщений: 6

Активные ссылки с разными стилями. Чистый JS
Добрый день!

Есть список ссылок:

<ul class="nav-list">
     <li data-filter="red" class="nav-list__item" id="red">Красный</li>
     <li data-filter="green" class="nav-list__item" id="green">Зеленый</li>
     <li data-filter="blue" class="nav-list__item" id="blue">Синий</li>
     <li data-filter="gray" class="nav-list__item" id="gray">Сброс</li>
</ul>



Нужно, чтобы в активном (нажатом) состоянии к каждой ссылке применялся свой собственный стиль.

Проблема: если указать для активной ссылки класс 'active', то все активные ссылки будут иметь один стиль, а это меня не устраивает.

При клике на новую ссылку, класс 'active' удаляется у старой ссылки и добавляется к новой. Это меня устраивает.

navItems.forEach(item => {
	item.addEventListener('click', event => {
		const filterValue = event.target.dataset.filter;
		navItems.forEach(item => {
    	item.classList.remove('active');
		event.target.classList.add('active');
		});
		});
	});



Если вместо класса 'active' передавать значение dataset посредством переменной filterValue, к ссылкам применяются те классы, которые нужны. Это хорошо.

Но при этом класс у старой ссылки не удаляется, и когда происходит клик по новой ссылке, обе ссылки становятся активными. Это плохо.

navItems.forEach(item => {
item.addEventListener('click', event => {
const filterValue = event.target.dataset.filter;
item.classList.remove(filterValue);
event.target.classList.add(filterValue);
});
});


Подскажите, пожалуйста, как можно решить эту проблему.

Последний раз редактировалось ixiz, 19.09.2023 в 23:41.
Ответить с цитированием
  #2 (permalink)  
Старый 19.09.2023, 23:41
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,493

<ul class="nav-list-1">
     <li data-filter="red" class="nav-list__item">Красный</li>
     <li data-filter="green" class="nav-list__item">Зеленый</li>
     <li data-filter="blue" class="nav-list__item">Синий</li>
     <li data-filter="gray" class="nav-list__item">Сброс</li>
</ul>
<style> 
  [data-filter="red"]:active {
    color: red
  }  
  [data-filter="green"]:active {
    color: green
  }  
  [data-filter="blue"]:active {
    color: blue
  }  
  [data-filter="gray"]:active {
    color: gray
  }  
</style>

<ul class="nav-list-2">
     <li style="--active-color: red" class="nav-list__item">Красный</li>
     <li style="--active-color: green" class="nav-list__item">Зеленый</li>
     <li style="--active-color: blue" class="nav-list__item">Синий</li>
     <li style="--active-color: gray" class="nav-list__item">Сброс</li>
</ul>
<style> 
  .nav-list-2 > li:active {
    color: var(--active-color);
  }  
</style>
__________________
29375, 35
Ответить с цитированием
  #3 (permalink)  
Старый 20.09.2023, 00:41
Новичок на форуме
Отправить личное сообщение для ixiz Посмотреть профиль Найти все сообщения от ixiz
 
Регистрация: 19.09.2023
Сообщений: 6

Спасибо за оперативный ответ!

Наверно, я не совсем точно описал проблему. При ховере и клике (hover и active) у меня всё работает.

Мне надо, чтобы активная ссылка имела оформление не только в процессе клика, а на протяжении всего времени, пока юзер не кликнул на другую ссылку.

Собственно, проблема в том, что если в JS я пишу ‘active’, то КО ВСЕМ ссылкам применяется ОДИН CSS класс .active. А мне нужно, чтобы У КАЖДОЙ ссылки было свое оформление.

Если же в JS я меняю ‘active’ на переменную filterValue, я в принципе получаю желаемое: каждая ссылка имеет свое оформление: значение dataset совпадает с названием CSS класса. Но это оформление не отключается при клике на новую ссылку. Нажал на красную, красная ссылка стала красной, нажал на зеленую, зеленая стала зеленой. А мне надо, чтобы при клике на зеленую она стала зеленой, а красная перестала быть красной.

Как-то так.
Ответить с цитированием
  #4 (permalink)  
Старый 20.09.2023, 01:42
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,070

ixiz,
<!DOCTYPE HTML>
<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
        .red {
            color: red;
        }

        .green {
            color: green;
        }

        .blue {
            color: blue;
        }

        .gray {
            color: gray;
        }
    </style>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const nav = document.querySelector('.nav-list');
            let active, filterValue;
            nav.addEventListener('click', ({ target }) => {
                if (target = target.closest('[data-filter]')) {
                    if (active) {
                        active.classList.remove(filterValue)
                    }
                    active = target;
                    filterValue = target.dataset.filter;
                    active.classList.add(filterValue)
                }
            })
        })
    </script>
</head>

<body>
    <ul class="nav-list">
        <li data-filter="red" class="nav-list__item" id="red">Красный</li>
        <li data-filter="green" class="nav-list__item" id="green">Зеленый</li>
        <li data-filter="blue" class="nav-list__item" id="blue">Синий</li>
        <li data-filter="gray" class="nav-list__item" id="gray">Сброс</li>
    </ul>
</body>

</html>
Ответить с цитированием
  #5 (permalink)  
Старый 20.09.2023, 01:47
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,070

Сообщение от ixiz
ОДИН CSS класс .active. А мне нужно, чтобы У КАЖДОЙ ссылки было свое оформление.

<!DOCTYPE HTML>
<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
        [data-filter="red"].active {
            color: red;
        }

         [data-filter="green"].active {
            color: green;
        }

         [data-filter="blue"].active {
            color: blue;
        }

         [data-filter="gray"].active {
            color: gray;
        }
    </style>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const nav = document.querySelector('.nav-list');
            let active;
            nav.addEventListener('click', ({ target }) => {
                if (target = target.closest('[data-filter]')) {
                    if (active) {
                        active.classList.remove('active')
                    }
                    active = target;
                    active.classList.add('active')
                }
            })
        })
    </script>
</head>

<body>
    <ul class="nav-list">
        <li data-filter="red" class="nav-list__item" id="red">Красный</li>
        <li data-filter="green" class="nav-list__item" id="green">Зеленый</li>
        <li data-filter="blue" class="nav-list__item" id="blue">Синий</li>
        <li data-filter="gray" class="nav-list__item" id="gray">Сброс</li>
    </ul>
</body>

</html>
Ответить с цитированием
  #6 (permalink)  
Старый 20.09.2023, 08:08
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,704

Можно меньше CSS
<!DOCTYPE HTML>
<html>
 
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
        [data-filter].active {
            color: var(--link-color);
        }
 
    </style>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const nav = document.querySelector('.nav-list');
            let active;
            nav.addEventListener('click', ({ target }) => {
                if (target = target.closest('[data-filter]')) {
                    active?.classList.remove('active')
                    active = target;
                    active.style.setProperty('--link-color', active.dataset.filter);
                    active.classList.add('active')
                }
            })
        })
    </script>
</head>
 
<body>
    <ul class="nav-list">
        <li data-filter="red" class="nav-list__item" id="red">Красный</li>
        <li data-filter="green" class="nav-list__item" id="green">Зеленый</li>
        <li data-filter="blue" class="nav-list__item" id="blue">Синий</li>
        <li data-filter="gray" class="nav-list__item" id="gray">Сброс</li>
    </ul>
</body>
 
</html>

Последний раз редактировалось voraa, 20.09.2023 в 11:15.
Ответить с цитированием
  #7 (permalink)  
Старый 20.09.2023, 10:47
Новичок на форуме
Отправить личное сообщение для ixiz Посмотреть профиль Найти все сообщения от ixiz
 
Регистрация: 19.09.2023
Сообщений: 6

Спасибо большое за ответы!
Ответить с цитированием
  #8 (permalink)  
Старый 20.09.2023, 13:45
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,493

ixiz, можно без js, но это уже на любителя:
<ul class="nav-list">
  <label>
    <input type="radio" name="color"/>
    <li style="--active-color: red" class="nav-list__item">
      Красный
    </li>
  </label>
  <label>
    <input type="radio" name="color"/>
    <li style="--active-color: green" class="nav-list__item">
      Зеленый
    </li>
  </label>
  <label>
    <input type="radio" name="color"/>
    <li style="--active-color: blue" class="nav-list__item">
      Синий
    </li>
  </label>
  <label>
    <input type="radio" name="color"/>
    <li style="--active-color: gray" class="nav-list__item">
      Сброс
    </li>
  </label>
</ul>

<style> 
  .nav-list input[type="radio"] {
    display: none;
  }
  .nav-list input[type="radio"]:checked + li {
    color: var(--active-color);
  }  
</style>



Кстати возможно тебе бы хватило :target если ссылки по хэшу.
__________________
29375, 35
Ответить с цитированием
  #9 (permalink)  
Старый 20.09.2023, 13:53
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,704

Aetae,
Оно конечно браузерами пропускается, но валидаторы вопят благим матом.
Дочерними элементами <ul> могут быть только <li>
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Изменение цвета ссылки с помощью js Alex Pacifik Элементы интерфейса 3 31.01.2012 15:08
JS IE8 добавление ссылки с якорем в историю mat_ppc Internet Explorer 0 21.01.2011 22:38
открытие ссылки на новой странице если нету js FRIE Общие вопросы Javascript 9 01.12.2010 12:50
Что лучше: библиотека или чистый JS? `p r o x y Библиотеки/Тулкиты/Фреймворки 4 26.11.2010 11:16
Как сделать ссылки кликабельными на js? JsEditor Элементы интерфейса 3 05.10.2010 15:30