21.10.2020, 13:55
|
Аспирант
|
|
Регистрация: 08.07.2019
Сообщений: 85
|
|
Сообщение от рони
|
Aruta,
менять надо класс элемента, а не стили элемента!!!
потому-что if (elem.style.borderColor == activeBorderColor)
activeBorderColor не содержит нужный цвет, строки 3 и 4, нужно вычислять, писать функцию которая вернёт нужный "цвет", браузеры устанавливают цвет параметра в своих единицах измерения, независимо что было в параметре установки (строка 40 и 59)!!!
поэтому лучше проверять класс элемента elem.classList.contains(), а ещё лучше не проверять а менять сразу elem.classList.toggle() и будет одна строка вместо строк 50 - 63.
|
Цвета пока не трогал, но переписал код.
Добавил 2 класса:
active-show - активированный фильтр - просто когда нажали на фильтр, чтобы посмотреть какие параметры фильтра выбрать можно
active - для активного фильтра с активным чекбоксом
Работает почти всё - осталась одна мелочь и вот её я не понял как и куда надо впихнуть верное условие:
if (click.target = любой соседний li || на самого себя || в любое другое место на document) {
if (текущий активный li имеет class('active-show') ){
li.classList.remove('active-show')
}
}
Последний раз редактировалось Aruta, 21.10.2020 в 13:58.
|
|
21.10.2020, 14:37
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,126
|
|
Aruta,
|
|
21.10.2020, 14:48
|
Аспирант
|
|
Регистрация: 08.07.2019
Сообщений: 85
|
|
Сообщение от рони
|
Aruta,
|
Да... забыл код добавить завтра докину
|
|
21.10.2020, 16:06
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,126
|
|
Aruta,
<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
<style type="text/css">
ul{
list-style: none;
}
.filter__list{
display: flex;
}
li.active-show .filter__list{
color: #8B4513;
font-weight: bold;
}
.filter__list + div{
display: none;
}
li.active-show .filter__list + div{
border: 1px solid #FF0000;
display: block;
}
.filter__list:after{
content: "▼"
}
li.active-show .filter__list:after{
content: "▲"
}
</style>
</head>
<body>
<ul class="results__filter-inner dflex">
<!-- Блок конкретного фильтра. Далее каждая группа фильтров обозначена li id="название фильтра" -->
<li id="gender">
<!--Блок названия группы фильтра и стрелочки -->
<div class="filter__name filter__list">
<div>Gender</div>
</div>
<!--Раскрывающийся список группы -->
<div class="filter__name__list-wrap dflex">
<div class="name__list-inner">
<div class="name__list">
<input type="checkbox" id="chk_men" class="toggle" name="chk_men" value="Men">
<label for="chk_men" class="name__list-label">Men</label>
</div>
<div class="name__list">
<input type="checkbox" id="chk_women" class="toggle" name="chk_women" value="Women">
<label for="chk_women" class="name__list-label">Women</label>
</div>
</div>
</div>
</li>
<li id="priority">
<div class="filter__name filter__list">
<div>Priority</div>
</div>
<div class="filter__name__list-wrap">
<div class="name__list-inner">
<div class="name__list">
<input type="checkbox" id="chk_color" class="toggle" name="chk_color" value="Color">
<label for="chk_color" class="name__list-label">Color</label>
</div>
<div class="name__list">
<input type="checkbox" id="chk_style" class="toggle" name="chk_style" value="Style">
<label for="chk_style" class="name__list-label">Style</label>
</div>
</div>
</div>
</li>
<li id="prod_type">
<div class="filter__name filter__list">
<div>Product type</div>
</div>
<div class="filter__name__list-wrap" >
<div class="name__list-inner">
<div class="name__list">
<input type="checkbox" id="chk_shirt" class="toggle" name="chk_shirt" value="Shirt">
<label for="chk_shirt" class="name__list-label">Shirt</label>
</div>
<div class="name__list">
<input type="checkbox" id="chk_blouse" class="toggle" name="chk_blouse" value="Blouse">
<label for="chk_blouse" class="name__list-label">Blouse</label>
</div>
<div class="name__list">
<input type="checkbox" id="chk_top" class="toggle" name="chk_top" value="Top">
<label for="chk_top" class="name__list-label">Top, T-shirt, Sweatshirt</label>
</div>
<div class="name__list">
<input type="checkbox" id="chk_sweater" class="toggle" name="chk_sweater" value="Sweater">
<label for="chk_sweater" class="name__list-label">Sweater</label>
</div>
</div>
</div>
</li>
<li>
<input type="checkbox" id="dublicate" class="toggle" name="dublicate">
<label for="dublicate">Remove dublicate</label>
</li>
<li>
<div class="filter__name clear">
<div>Clear</div>
</div>
</li>
</ul>
<script>
const ul = document.querySelector('.results__filter-inner');
let tempLi;
document.addEventListener('click', event => {
let filterUl = event.target.closest('ul');
let li = event.target.closest('li');
if (tempLi && li != tempLi) {
tempLi.classList.remove('active-show');
tempLi = null;
}
if (filterUl == ul) {
if (li.querySelector('.filter__list')) {
tempLi = li;
let input = event.target.closest('[type="checkbox"]');
if (input) li.querySelectorAll('[type="checkbox"]').forEach(el => el != input && (el.checked = false));
if (event.target.closest('.filter__list')) tempLi.classList.toggle('active-show');
}
if (li.querySelector('.clear')) {
ul.querySelectorAll(':checked').forEach(el => el.checked = false);
}
}
})
</script>
</body>
</html>
|
|
22.10.2020, 05:43
|
Аспирант
|
|
Регистрация: 08.07.2019
Сообщений: 85
|
|
Сообщение от рони
|
Aruta,
|
Неделю делал это... фуууф.
Добавляю код - дописал его всё же до конца и правильно работает
const buttons = document.querySelectorAll('.results__filter-inner>li');
const subMenuAll = document.querySelectorAll('.filter__name__list-wrap');
let activeBorderColor ='rgb(255, 123, 172)';
let activeColor = 'rgb(34, 7, 24)';
//функция HIDE всех нужных блоков по классу
const dnoneStyle = () => {
subMenuAll.forEach((dnone) => {
dnone.style.display = "none";
});
}
const disActive = () =>{
for (let i=0; i<buttons.length; i++){
if (buttons[i].classList.contains('active-show')){
buttons[i].classList.remove('active-show');
}
}
}
//Закрытие меню при клике вне меню
const closeFilter = () => {
document.addEventListener('click', e => {
if(!buttons.target) {
subMenuAll.forEach((e) => {
dnoneStyle()
})
}
disActive()
})
}
// Открытие/закрытие подменю при нажатии на название фильтра
buttons.forEach((elem) => {
let subMenu = elem.querySelector('.filter__name__list-wrap');
let clear = elem.querySelector('.clear');
const activeFilter = () =>{
// elem.classList.toggle('active-show');
buttons.forEach( (chbx) => {
let inputs = chbx.querySelectorAll('input');
for (let i=0; i<inputs.length; i++){
inputs[i].onchange = () =>{
let inputParent = chbx.closest('li'); //обращаемся к родителю элемента
if (!inputs[i].checked){
inputParent.classList.remove('active-filter');
inputs[i].classList.remove('active_param');
} else {
inputParent.classList.add('active-filter');
inputs[i].classList.add('active_param');
}
}
}
});
}
elem.addEventListener('click', (subElem) => {
const filterButtons = () => {
subElem.stopPropagation();
//если имеется выпадающий список у фильтра
if (subMenu){
if (subMenu.style.display != "block"){
dnoneStyle();
subMenu.style.display = "block";
//перебор checkbox, чтобы отмечался только один в фильтре
let inputs= elem.getElementsByTagName('input');
for (var i = inputs.length-1; i >= 0; -- i) {
inputs[i].onclick = function () {
for (var j = inputs.length-1; j >= 0; -- j) {
if (inputs[j] != this) inputs[j].checked = false;
}
}
}
activeFilter();
//запрет на всплытие клика выше выпадающего списка, т.е. не будет срабатывать на родителе.
subMenu.addEventListener('click', (g) => {
g.stopPropagation();
});
} else {
dnoneStyle();
}
} else { //если нет выпадающего списка у фильтра
dnoneStyle();
return;
}
}
//снятие окраски фильтра, если он не активен или он не ракскрыт
if (!clear){
for (let i = 0; i<buttons.length; i++){
if(!elem.classList.contains('active-show')){
elem.classList.toggle('active-show');
} else {
disActive()
}
}
}
//применяем функцию фильтров
filterButtons();
//сброс активных фильтра - CLEAR
if (clear){
for (let i=0; i<buttons.length; i++){
buttons[i].classList.remove('active-filter');
buttons[i].classList.remove('active-show');
}
buttons.forEach( (chbx) => {
let inputs = chbx.querySelectorAll('input');
for (let i=0; i<inputs.length; i++){
inputs[i].classList.remove('active_param');
inputs[i].checked = false;
}
})
}
});
});
closeFilter();
Последний раз редактировалось Aruta, 22.10.2020 в 09:19.
|
|
22.10.2020, 05:46
|
Аспирант
|
|
Регистрация: 08.07.2019
Сообщений: 85
|
|
рони,
Сообщение от рони
|
const ul = document.querySelector('.results__filter-inner');
let tempLi;
document.addEventListener('click', event => {
let filterUl = event.target.closest('ul');
let li = event.target.closest('li');
if (tempLi && li != tempLi) {
tempLi.classList.remove('active-show');
tempLi = null;
}
if (filterUl == ul) {
if (li.querySelector('.filter__list')) {
tempLi = li;
let input = event.target.closest('[type="checkbox"]');
if (input) li.querySelectorAll('[type="checkbox"]').forEach(el => el != input && (el.checked = false));
if (event.target.closest('.filter__list')) tempLi.classList.toggle('active-show');
}
if (li.querySelector('.clear')) {
ul.querySelectorAll(':checked').forEach(el => el.checked = false);
}
}
})
|
я в шоке от лаконичности кода
но он не работает у меня - ничего не происходит, а при нажатии на document вне фильтров иногда ошибка вылазит:
Cannot read property 'querySelector' of null.
Теперь интересно на сколько мой код мне сократить можно
Последний раз редактировалось Aruta, 22.10.2020 в 07:52.
|
|
22.10.2020, 08:24
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,750
|
|
const closeFilter = () => {
document.addEventListener('click', e => {
if(!buttons.target) {
subMenuAll.forEach((e) => {
dnoneStyle()
})
}
disActive()
})
}
Что такое buttons.target ?
|
|
22.10.2020, 08:52
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,126
|
|
Сообщение от Aruta
|
Cannot read property 'querySelector' of null.
|
допишите if( li && li.querySelector... строки 12 и 18 пост #16
|
|
22.10.2020, 09:54
|
Аспирант
|
|
Регистрация: 08.07.2019
Сообщений: 85
|
|
рони,
Понял почему не работает, но это уже в css надо лезть мне и пару примочек дописать, т.к. не всё работает как надо было, но нужная основа прописана получается в вашем коде.
Но всё же поражаюсь - у меня ровно 100строк, а у вас 20 (или чуть больше если добавить всё что нужно) - снимаю шляпу просто и говорю огромное спасибо за показанное
Один вопрос остался только по поводу кол-ва строк:
- это у меня с логикой проблема и можно было строк в 50 уложиться (как для новичка) или это от незнания js и для обучающегося это нормальный код(мой)?
Последний раз редактировалось Aruta, 22.10.2020 в 10:12.
|
|
22.10.2020, 10:07
|
Аспирант
|
|
Регистрация: 08.07.2019
Сообщений: 85
|
|
Сообщение от voraa
|
Что такое buttons.target ?
|
voraa, проверка условия "если клик не по одному из элементов массива buttons"
Последний раз редактировалось Aruta, 22.10.2020 в 10:10.
|
|
|
|