Лучший способ связать HTML-элемент с элементом массива

#javascript #html

#javascript #HTML

Вопрос:

Я создаю карточную игру, и способ, которым я ее настроил в настоящее время, заключается в том, что каждая карта представляет собой массив из двух значений, значения number и string масти.

 var deck = {
    cards: makeDeck(),
    shuffle: function () {
        for (var i = 0; i < 1000; i  ) {
            var card1 = Math.floor((Math.random() * this.cards.length));
            var card2 = Math.floor((Math.random() * this.cards.length));
            var temp = this.cards[card1];

            this.cards[card1] = this.cards[card2];
            this.cards[card2] = temp;
        }
        console.log("Deck Shuffled");
    }
}

function makeDeck() {
    var cards = new Array;
    for (let i = 6; i < 15; i  ) {
        cards.push(Card(i, 'spade'), Card(i, 'diamonds'), Card(i, 'clubs'), Card(i, 'hearts'));
    }
    return cards;
}

function renderDeck() {
    deck.cards.forEach(element => {
        var card = document.createElement("span");
        card.classList.add("deck", element[1]);
        card.innerHTML = element[0]   "<br />"   element[1];
        if (element === trumpCard) {
            card.classList.add("trump_card");
        }
        document.body.appendChild(card);
    });
}
  

Все они находятся внутри deck массива, и у меня есть функция, которая создаст <span> элемент для каждой карты. Теперь, когда игрок взаимодействует с картами, он нажимает на <span> элемент, но большую часть моей логики и тому подобное гораздо проще выполнить, используя массив значений и мастей. Мое текущее решение состояло в том, чтобы просто создать новые переменные в каждой функции для выбранного элемента, используя innerHTML , вот так:

 var value = parseInt(el.innerHTML.substr(0, el.innerHTML.indexOf('<')));
var suit = el.innerHTML.substr(el.innerHTML.indexOf('>')   1, el.innerHTML.length);
  

Это большая проблема, и мне было интересно, могу ли я в любом случае легко связать каждый из них <span> с соответствующим элементом массива. Я думал, может быть, что-нибудь с id s, но не уверен в реализации, и если это лучший способ сделать это.

Комментарии:

1. Кажется, что вы ищете ответ в чистом js, но стоит упомянуть, что интерфейсные фреймворки делают это тривиальным, например. deck.map((card, index) => { return (<span key={index}>{card.value} of {card.suit}</span>); }); — когда deck изменяется, меняется и DOM.

2. Да, я надеялся на ванильное решение этой проблемы, поскольку я все еще новичок во внешнем интерфейсе, но я буду иметь это в виду на будущее, на случай, если я захочу переделать игру с использованием фреймворка. Ty

Ответ №1:

Если я правильно понимаю, вы пытаетесь получить доступ к number и suit из необработанных элементов DOM. Я бы использовал для этого атрибуты HTML-данных:

В вашей функции визуализации:

 card.dataset.value = element[0];
card.dataset.suit = element[1];
  

Затем вы сможете получить доступ к значениям позже с помощью el.dataset.value и el.dataset.suit .

Вы также можете получить NodeList список всех элементов с указанным значением / suit, вызвав что-то вроде:

 document.querySelectorAll("[data-suit='spade']");
  

Вы можете прочитать больше об атрибутах данных в MDN.

Комментарии:

1. Да, это кажется отличным решением, большое вам спасибо 🙂

Ответ №2:

В первую очередь для этого вам действительно не нужны отдельные массивы. Если вы создадите свои span элементы и присвоите каждому id значение, представляющее конкретную карточку, которую он представляет, и класс, объединяющий это span с классификацией card , например:

 <span id="h12" class="card">Queen of Hearts</span>
  

Затем вы можете собрать все «карточки» в коллекцию, подобную этой:

 document.querySelectorAll(".card");
  

И эта коллекция может быть проиндексирована или зациклена.

Комментарии:

1. В моих функциях мне нужно, например, сделать определенные карты воспроизводимыми на основе их атрибута. Вместо id это, кажется, усложняет задачу, поскольку мне пришлось бы получить значение карты и масть, выполнив что-то похожее на то, что я имел в своем примере с использованием substr на id . В качестве конкретного примера, в игре вы разыгрываете карты, и ваш противник должен защищаться. Они защищаются, разыгрывая карту, которая соответствует масти, но имеет большее значение. У меня была бы функция, которая предоставляла бы всем совпадающим картам onClick функцию, позволяющую игроку разыгрывать эту карту.