#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
функцию, позволяющую игроку разыгрывать эту карту.