сортировка по критерию
у меня есть n-ное количество карточек товара, с указанной внутри ценной, так же есть выпадающее меню с выбором критерия, как можно выстроить карточки в порядке убывания/возрастания по одному из критериев?
function dropMenu() {
let wind = document.querySelector('.select');
let drop = document.querySelector('.select__drop');
wind.onclick = () => {
if (drop.style.display == "none") {
drop.style.display = "block";
} else {
drop.style.display = "none";
}
}
}
function selectPar() {
let selected = document.querySelector('.select').querySelector('.selected');
let elem = document.querySelector('.select__drop').querySelectorAll('.drop__selected');
elem.forEach(el => {
el.onclick = () => {
selected.innerHTML = el.innerText;
}
})
}
dropMenu()
selectPar()
.b {
display: flex;
}
.block {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
width: 500px;
margin-right: 50px;
}
.card {
width: 100px;
height: 100px;
text-align: center;
padding-top: 10px;
}
.select {
width: 150px;
height: 20px;
border: 1px solid black;
cursor: pointer;
}
.selected {
margin: 0px;
}
.select__drop {
width: 150px;
height: 100px;
border: 1px solid red;
position: adsolute;
margin-top: 10px;
padding-left: 15px;
}
.drop__selected {
cursor: pointer;
transition: all .5s ease;
}
.drop__selected:hover {
transform: scale(1.1);
}
<div class="b">
<div class="block">
<div class="card" style="background:red;">
<p class="card__title">
Товар 1
</p>
<p class="card__price">
1050
</p>
</div>
<div class="card" style="background:green;">
<p class="card__title">
Товар 2
</p>
<p class="card__price">
1500
</p>
</div>
<div class="card" style="background:blue;">
<p class="card__title">
Товар 3
</p>
<p class="card__price">
1000
</p>
</div>
<div class="card" style="background:grey;">
<p class="card__title">
Товар 4
</p>
<p class="card__price">
5000
</p>
</div>
<div class="card" style="background:orange;">
<p class="card__title">
Товар 5
</p>
<p class="card__price">
2000
</p>
</div>
<div class="card" style="background:yellow;">
<p class="card__title">
Товар 6
</p>
<p class="card__price">
900
</p>
</div>
<div class="card" style="background:white;">
<p class="card__title">
Товар 7
</p>
<p class="card__price">
1200
</p>
</div>
<div class="card" style="background:pink;">
<p class="card__title">
Товар 8
</p>
<p class="card__price">
1500
</p>
</div>
</div>
<div class="select">
<p class="selected">
по умолчанию
</p>
<div class="select__drop" style="display: none;">
<p class="drop__selected">
по убыванию
</p>
<p class="drop__selected">
по возрастанию
</p>
</div>
</div>
</div>
Ответы (1 шт):
Наверняка можно хранить данные в структуре и согласно им менять положение элементов. Но для наглядности сортирую массив с элементами .card согласно логике текущего option. Элементы отсортированного массив помещаю в собственный контейнер (где они и находятся) в установленном ранее порядке методом .prepend(). Так как одновременно на странице может существовать только один элемент, он не добавляется, а перемещается в начало контейнера.
Возможно, лучше будет использовать .append(), тогда надо просто поменять порядок сортировок на обратный.
При одинаковых значениях цены дополнительной проверки не проводит, можно по исходным номерам тогда располагать.
const block = document.querySelector('.block');
const select = document.querySelector('select');
select.addEventListener('change', e => {
const val = e.target.value;
let cards = [...block.querySelectorAll('.card')];
switch(val){
case 'по возрастанию':
cards.sort((a,b) => {
let priceA = +a.querySelector('.card__price').textContent;
let priceB = +b.querySelector('.card__price').textContent;
return priceB - priceA;
})
break;
case 'по убыванию':
cards.sort((a,b) => {
let priceA = +a.querySelector('.card__price').textContent;
let priceB = +b.querySelector('.card__price').textContent;
return priceA - priceB;
})
break;
case 'по умолчанию':
cards.sort((a,b) => {
let titleA= +a.querySelector('.card__title').textContent.match(/\d+/)[0];
let titleB = +b.querySelector('.card__title').textContent.match(/\d+/)[0];
return titleB - titleA;
})
break;
}
cards.forEach(card => {
block.prepend(card);
})
})
.b {
display: flex;
}
.block {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
width: 500px;
margin-right: 50px;
}
.card {
width: 100px;
height: 100px;
text-align: center;
padding-top: 10px;
}
<div class="b">
<div class="block">
<div class="card" style="background:red;">
<p class="card__title">
Товар 1
</p>
<p class="card__price">
1050
</p>
</div>
<div class="card" style="background:green;">
<p class="card__title">
Товар 2
</p>
<p class="card__price">
1500
</p>
</div>
<div class="card" style="background:blue;">
<p class="card__title">
Товар 3
</p>
<p class="card__price">
1000
</p>
</div>
<div class="card" style="background:grey;">
<p class="card__title">
Товар 4
</p>
<p class="card__price">
5000
</p>
</div>
<div class="card" style="background:orange;">
<p class="card__title">
Товар 5
</p>
<p class="card__price">
2000
</p>
</div>
<div class="card" style="background:yellow;">
<p class="card__title">
Товар 6
</p>
<p class="card__price">
900
</p>
</div>
<div class="card" style="background:white;">
<p class="card__title">
Товар 7
</p>
<p class="card__price">
1200
</p>
</div>
<div class="card" style="background:pink;">
<p class="card__title">
Товар 8
</p>
<p class="card__price">
1500
</p>
</div>
</div>
</div>
<select style="position:fixed;top:10px;right:50px">
<option selected>по умолчанию</option>
<option>по возрастанию</option>
<option>по убыванию</option>
</select>