Я создаю css-флип-карты для проектов, используя теги шаблонов Django для перебора карточек. Все кнопки переворачивают только первую карту

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.