javascript #jquery #css #django #responsive
#javascript #jquery #css #django #отзывчивый
Вопрос:
Как сказано в названии. Я хорошо знаю Django, но все еще привыкаю использовать JS для такого рода вещей. Я перебираю карточки с помощью {% для project в projects %} , и все отображается так, как должно. И, когда я нажимаю кнопку на первой карточке, она отлично переворачивает карту. Однако, когда я нажимаю кнопку любой другой карты, они также переворачивают и первую карту, вместо того, чтобы переворачивать саму следующую карту. Я думаю, что это как-то связано с идентификатором divs или меток, и я попробовал несколько вещей, но я не совсем понял это.
Вот необходимый HTML:
<div class="wrapper">
{% for project in projects %}
<div class="card">
<input type="checkbox" id="card1" class="more" aria-hidden="true">
<div class="content">
<div class="front"
style="background-image: url({{ project.image }})">
<div class="inner">
<h2>{{ project.title}}</h2>
<label for="card1" class="button" aria-hidden="true">
Details
</label>
</div>
</div>
<div class="back">
<div class="inner">
<div class="info">
</div>
<div class="description">
<p>{{ project.description }}</p>
</div>
<div class="location">Warsaw, Poland</div>
<div class="price">38€ / day</div>
<label for="card1" class="button return" aria-hidden="true">
<i class="fas fa-arrow-left"></i>
</label>
</div>
</div>
</div>
</div>
{% endfor %}
CSS, относящийся к карточкам:
<style>
.wrapper {
display: flex;
flex-flow: row wrap;
justify-content: center;
}
.card {
width: 420px;
height: 340px;
margin: 1em;
perspective: 1500px;
}
.card .content {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: transform 0.8s cubic-bezier(0.75, 0, 0.85, 1);
}
.more:checked ~ .content {
transform: rotateY(180deg);
}
.front,
.back {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
backface-visibility: hidden;
transform-style: preserve-3d;
border-radius: 6px;
}
.front .inner,
.back .inner {
height: 100%;
display: grid;
padding: 1.5em;
transform: translateZ(90px) scale(0.75);
}
.front {
background-color: #fff;
background-size: cover;
background-position: center center;
}
.front:after {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: block;
border-radius: 6px;
backface-visibility: hidden;
background-image: url("{{ project.image }}");
}
.front .inner {
grid-template-rows: 5fr 1fr 1fr 2fr 1fr;
justify-items: center;
}
.front h2 {
grid-row: 2;
margin-bottom: 0.3em;
text-transform: uppercase;
letter-spacing: 3px;
color: #fff;
font-weight: 500;
text-shadow: 0 0 6px rgba(0, 0, 0, 0.1);
}
.front .rating i {
margin: 0 1px;
}
.back {
transform: rotateY(180deg);
background-color: #fff;
border: 2px solid #f0f0f0;
}
.back .inner {
grid-template-rows: 1fr 2fr 1fr 2fr 14fr 1fr 1fr;
grid-template-columns: repeat(3, auto);
grid-column-gap: 0.8em;
justify-items: center;
}
.back .info {
position: relative;
display: flex;
align-items: center;
color: #355cc9;
grid-row: 3;
}
.back .info:not(:first-of-type):before {
content: "";
position: absolute;
left: -0.9em;
height: 18px;
width: 1px;
background-color: #ccc;
}
.back .info span {
font-size: 2em;
font-weight: 700;
}
.back .info i {
font-size: 1.2em;
}
.back .info i:before {
background: linear-gradient(40deg, #355cc9, #438af3);
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
}
.back .info .icon {
margin-left: 0.3em;
}
.back .info .icon span {
display: block;
margin-top: -0.25em;
font-size: 0.8em;
font-weight: 600;
white-space: nowrap;
}
.back .description {
grid-row: 5;
grid-column: 1/-1;
font-size: 0.86em;
border-radius: 5px;
font-weight: 600;
line-height: 1.4em;
overflow: auto;
color: #355cc9;
padding-right: 10px;
}
.back .location,
.back .price {
font-weight: 600;
color: #355cc9;
grid-row: 1;
font-size: 0.86em;
}
.back .location {
grid-column: 1/3;
justify-self: left;
}
.back .price {
grid-column: 3/-1;
justify-self: right;
}
.back .button {
grid-column: 1/-1;
justify-self: center;
}
.button {
grid-row: -1;
text-transform: uppercase;
letter-spacing: 1px;
font-weight: 600;
cursor: pointer;
display: block;
padding: 0 1.5em;
height: 3em;
line-height: 2.9em;
min-width: 3em;
background-color: transparent;
border: solid 2px #fff;
color: #fff;
border-radius: 4px;
text-align: center;
left: 50%;
backface-visibility: hidden;
transition: 0.3s ease-in-out;
text-shadow: 0 0 6px rgba(0, 0, 0, 0.3);
}
.button:hover {
background-color: #fff;
box-shadow: 0 0 50px rgba(0, 0, 0, 0.5);
text-shadow: none;
color: #355cc9;
}
.button.return {
line-height: 3em;
color: #355cc9;
border-color: #355cc9;
text-shadow: none;
}
.button.return:hover {
background-color: #355cc9;
color: #fff;
box-shadow: none;
}
::-webkit-scrollbar {
width: 5px;
}
::-webkit-scrollbar-track {
background: #f1f1f1;
}
::-webkit-scrollbar-thumb {
background: #859ddf;
}
::-webkit-scrollbar-thumb:hover {
background: #355cc9;
}
</style>
И javascript (в какой-то момент у меня был другой скрипт jquery, но это то, что у меня есть сейчас:
(function () {
var tab = document.querySelector('.card');
document.getElementById('card1').addEventListener('click', function () {
tab.classList.add('back');
}, false);
document.getElementById('card1').addEventListener('click', function () {
tab.classList.remove('front');
}, false);
})();
</script>
Я не уверен, что было бы полезно что-нибудь еще, но если у кого-нибудь есть хорошее представление о том, что может происходить, это было бы невероятно полезно. Это единственная загвоздка, с которой я столкнулся, когда мне приходилось задавать вопрос для моих последних нескольких проектов. Это просто раздражает. Спасибо.
Ответ №1:
Причина, по которой все кнопки переворачивают только первую карточку, заключается в том, что ваш идентификатор жестко задан с помощью «card1», значение идентификатора в html должно быть уникальным. Идентификатор «card1» предназначен только для первого элемента, который использует тот же идентификатор
<input type="checkbox" id="card1" class="more" aria-hidden="true">
Вы должны генерировать динамический идентификатор для каждой итерации, так что, например, вы могли бы сгенерировать значение ids с помощью «card1», «card2», «card3» и т.д.
То же самое с js
document.getElementById('card1').addEventListener('click', function () {
tab.classList.add('back');
}, false);
document.getElementById('card1').addEventListener('click', function () {
tab.classList.remove('front');
}, false);
Вы должны создать динамический прослушиватель событий для каждого идентификатора
Посмотрите, как html id работает с HTML id
Комментарии:
1. Спасибо, я действительно ценю ваш ответ. У меня было ощущение, что так оно и было, так что, по крайней мере, я знаю, на чем сосредоточиться сейчас. Я имею в виду, что в любом случае это была самая очевидная проблема. Я использую Django, поэтому мне, вероятно, потребуется заменить card1 идентификатором объекта базы данных или чем-то еще. Мне просто нужно точно выяснить, что работает. Еще раз спасибо за помощь.
Ответ №2:
Итак, после того, как Dhia Aziz Rizqi подтвердил мои подозрения, что на самом деле проблема заключалась в идентификаторе; и не было никакой другой основной проблемы, я сразу же попытался динамически вызвать идентификатор проекта с помощью Django внутри функции JS. Это сработало отлично.
Раньше я не использовал теги шаблонов Django внутри функции JS, поэтому я не был уверен, как это будет, но для всех, кто столкнется с этой проблемой…
Javascript необходимо изменить на это:
<script>
(function () {
var tab = document.querySelector('.card');
document.getElementById('{{ project.id }}').addEventListener('click', function () {
tab.classList.add('back');
}, false);
document.getElementById('{{ project.id }}').addEventListener('click', function () {
tab.classList.remove('front');
}, false);
})();
</script>
И HTML к этому:
<div class="wrapper">
{% for project in projects %}
<div class="card">
<label for="{{ project.id }}"></label><input type="checkbox" id="{{ project.id }}" class="more" aria-hidden="true">
<div class="content">
<div class="front"
style="background-image: url({{ project.image }})">
<div class="inner">
<h2>{{ project.title}}</h2>
<label for="{{ project.id }}" class="button" aria-hidden="true">
Details
</label>
</div>
</div>
<div class="back">
<div class="inner">
<div class="info">
</div>
<div class="description">
<p>{{ project.description }}</p>
</div>
<div class="location">Warsaw, Poland</div>
<div class="price">38€ / day</div>
<label for="{{ project.id }}" class="button return" aria-hidden="true">
<i class="fas fa-arrow-left"></i>
</label>
</div>
</div>
</div>
</div>
{% endfor %}
Решение состояло в том, чтобы просто динамически добавлять идентификатор проекта вместо фиксированного идентификатора.
Это прекрасно работает с Django.