Как после второго клика обнулить значения всех переменных?
Помогите кто-нибудь, а то кранты!!!
Есть контейнер с карточками. Нужно:
после первого клика карточка выделяется;
после второго клика на второй карточке они (карточки) меняются местами с первой;
двумя следующими кликами выделяются новые пары карточек и меняются между собой;
... и тд. ...
Что сделано:
созданы два обработчика событий, которые находят две целевые карточки и меняют их местами, после этого обнуляются их переменные; Казалось бы, все хорошо? Но!!! кликнутая карточка #2 почему-то не обнуляется и запоминается как первый клик! То есть, если в начале нажали по первой карточке, она сначала (как и нужно) перемещается на место нажатой вторым кликом, а если нажимают по третей карточке (чтобы поменять две новые пары карточек), то эта карточка перескакивает на место третьей, и так мигрирует по всему контейнеру после новых кликов :((((( Пробовал обнулять селектор со всеми карточками, прекращал обработчики кликов - тогда скрипт перестает работать.
Варианты решения проблемы:
- Может быть, прикрутить массив?
- в конце скрипта обнулить селектор со всеми карточками и как-то (как?) потребовать возвратить текущее событие на начальный этап (м.б. при помощи
if cardAll = null {...}). - Задать счетчик кликов, после второго клика обнулить все переменные? Приведите пожалуйста примеры.
P.S. Желательно, на чистом JS
let cardHolder = document.querySelector('.offers__wrapper'),
cardAll = document.querySelectorAll('.card'),
cardItems = document.querySelectorAll('.card__comeback');
cardHolder.addEventListener('click', (e) => {
let star = e.target.closest('.card__comeback');
let cardCurrent = e.target.closest('.card');
if (star) {
cardItems.forEach((item, i) => {
if (item === star) {
cardItems[i].classList.add("card__comeback--active");
if (cardCurrent) {
cardAll.forEach((item, i) => {
if (item === cardCurrent) {
let a = cardCurrent;
cardHolder.addEventListener('click', (e) => {
let star2 = e.target.closest('.card__comeback');
let cardCurrent2 = e.target.closest('.card');
if (star2) {
cardItems.forEach((item, i) => {
if (item === star2) {
cardItems[i].classList.add("card__comeback--active");
if (cardCurrent2) {
cardAll.forEach((item, i) => {
if (item === cardCurrent2) {
let b = cardCurrent2;
let temp;
temp = a.innerHTML;
a.innerHTML = b.innerHTML;
b.innerHTML = temp;
a = null;
b = null;
temp = null;
};
});
}
}
});
};
});
};
});
}
}
});
};
});
<div class="offers__wrapper">
<div class="card">
<div class="card__img">
<div class="card__for-sell">For Sell
</div>
<div class="card__hearth"></div>
<div class="card__comeback"></div>
<div class="card__type">Commercial Property
</div>
<img src="img/main/card/property-01.png" alt="">
</div>
<h3 class="card__title">Countryside Modern Lake View</h3>
<div class="card__location">Poughkeepsie, New York</div>
<div class="card__price">$28,000</div>
<div class="card__conditions">
<div class="beds">
<div class="beds__icon"></div>
<div class="amount">Beds 3</div>
</div>
<div class="baths">
<div class="baths__icon"></div>
<div class="amount">Baths 1</div>
</div>
<div class="square">
<div class="square__icon"></div>
<div class="amount">2200 Sqft</div>
</div>
</div>
</div>
<div class="card">
</div>
...
...
<div class="card">
</div>
</div>
Ответы (1 шт):
Надеюсь я правильно понял задачу, что вам нужно менять элементы местами.
Накидал такой вариант:
let selected = false; // Тут будем хранить индекс первого выбранного элемента.
document.querySelector('.cards').addEventListener('click', e => { // Вешаем ивент на клик | делегирование
const target = e.target.closest('.cards-item'); // Получаем элемент для перемещения
if(target) { // Проверяем что такой есть - это для делегирования
// Если нажат будет тот, который уже выделен, то мы снимем с него класс и отменим действие
if(target.classList.contains('cards-item-selected')) {
target.classList.remove('cards-item-selected');
selected = false;
return false;
}
// А тут основная логика
if(selected === false) { // Если нет индекса первого выброного элемента
selected = [...target.parentElement.children].indexOf(target); // получаем этот индекс и сразу записываем
target.classList.add('cards-item-selected'); // Вешаем ему класс, чтобы выделить
} else { // А тут будет действие для второго выделеного блока
const parent = target.parentElement; // Получаем родителя
const i = [...parent.children].indexOf(target); // Получаем индекс второго нажатого блока
const childrens = parent.children; // Получаем все блоки
const clones = [childrens[selected].cloneNode(true), childrens[i].cloneNode(true)]; // Чтобы проще было поменять, мы клонируем наши выбранные элементы. Таким способом сохронятся даже повешанные на них ивенты.
// Далее логика такая: заменяем А клоном Б, а Б клоном А.
parent.replaceChild(clones[0], childrens[i]);
parent.replaceChild(clones[1], childrens[selected]);
childrens[i].classList.remove('cards-item-selected'); // Удаляем класс выделения
// P.s. удаляем класс не у selected, а у i, потому что под этими индексами уже поменяные элементы.
selected = false; // Указываем что "выбранный" - не выбран.
}
}
});
.cards {
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: wrap;
width: 180px;
}
.cards-item {
display: flex;
justify-content: center;
align-items: center;
width: 50px;
height: 50px;
background-color: #ccc;
margin-right: 10px;
margin-bottom: 10px;
cursor: pointer;
}
.cards-item-selected {
box-shadow: 0 0 0 1px #09f;
}
<div class="cards">
<div class="cards-item">1</div>
<div class="cards-item">2</div>
<div class="cards-item">3</div>
<div class="cards-item">4</div>
<div class="cards-item">5</div>
<div class="cards-item">6</div>
</div>
Код на ES6, если важно)