Создание раздела комментариев
К элементу (комментарий), который создается из данных, введенных в input, добавляется счетчик рейтинга в формате кнопка "минус" - счетчик - кнопка "плюс", на которые можно нажать только один раз либо кнопка минус либо кнопка плюс - с шагом 1.
Как сделать эти кнопки и счетчик рейтинга уникальными для каждого комментария?
Ответы (1 шт):
Автор решения: eccs0103
→ Ссылка
Вот вам каркас
Это ещё совсем малая часть того, что стоит написать для нормалных комментариев, но как бы… все начинается с основ.
class CommentData {
/**
* @param {String} text
* @param {String} user
*/
constructor(text, user) {
this.text = text;
this.user = user;
}
/** @type {String} */
text;
/** @type {String} */
user;
/** @type {Map<String, (`up` | `down`)>} */
votes = new Map();
/** @readonly */
get up() {
return Array.from(this.votes).filter(([user, type]) => type == `up`).map(([user]) => user);
}
/** @readonly */
get down() {
return Array.from(this.votes).filter(([user, type]) => type == `down`).map(([user]) => user);
}
}
/** @type {Array<CommentData>} */
const comments = [];
const userIdentifier = `--user identifier--`;
const templateCommentContainer = ( /** @type {HTMLTemplateElement} */ (document.querySelector(`template#comment-container`)));
const container = templateCommentContainer.parentElement;
if (!container) {
throw new ReferenceError(`Element 'container' isn't defined.`);
}
const formCommentForm = ( /** @type {HTMLFormElement} */ (document.querySelector(`form#comment-form`)));
const inputComment = ( /** @type {HTMLInputElement} */ (document.querySelector(`input#comment`)));
formCommentForm.addEventListener(`submit`, (event) => {
if (formCommentForm.checkValidity()) {
const comment = new CommentData(inputComment.value, userIdentifier);
comments.push(comment);
const sectionCommentContainer = ( /** @type {HTMLElement} */ (container.appendChild(templateCommentContainer.content.querySelector(`section.comment-container`).cloneNode(true)))); {
const spanVotes = ( /** @type {HTMLSpanElement} */ (sectionCommentContainer.querySelector(`span.votes`)));
const buttonUpVote = ( /** @type {HTMLButtonElement} */ (sectionCommentContainer.querySelector(`button.up-vote`)));
buttonUpVote.addEventListener(`click`, (event) => {
if (comment.votes.has(userIdentifier)) {
comment.votes.delete(userIdentifier);
} else {
comment.votes.set(userIdentifier, `up`);
}
spanVotes.innerText = `${comment.up.length - comment.down.length}`;
});
const buttonDownVote = ( /** @type {HTMLButtonElement} */ (sectionCommentContainer.querySelector(`button.down-vote`)));
4;
buttonDownVote.addEventListener(`click`, (event) => {
if (comment.votes.has(userIdentifier)) {
comment.votes.delete(userIdentifier);
} else {
comment.votes.set(userIdentifier, `down`);
}
spanVotes.innerText = `${comment.up.length - comment.down.length}`;
});
const spanComment = ( /** @type {HTMLSpanElement} */ (sectionCommentContainer.querySelector(`span.comment`)));
spanComment.innerText = comment.text;
}
}
});
section.comment-container {
display: grid;
grid: 'up-vote comment' max-content 'votes comment' max-content 'down-vote comment' max-content '- comment' 1fr / max-content 1fr;
place-items: center;
gap: 4px;
}
section.comment-container>button.up-vote {
grid-area: up-vote;
}
section.comment-container>span.votes {
grid-area: votes;
}
section.comment-container>button.down-vote {
grid-area: down-vote;
}
section.comment-container>span.comment {
grid-area: comment;
width: 100%;
height: 100%;
overflow: auto;
}
<div style="max-width: 300px; display: flex; flex-direction: column-reverse;">
<template id="comment-container">
<section class="comment-container">
<button class="up-vote">↑</button>
<span class="votes">0</span>
<button class="down-vote">↓</button>
<span class="comment"></span>
</section>
</template>
<form method="dialog" id="comment-form">
<input id="comment" type="text" required minlength="1" placeholder="Enter to send">
</form>
</div>
Вам предстоит ещё...
- получить уникальный идентификатор пользователя и передать его в константу
userIdentifierвместо обычной строки который я передал. По поводу уникального значеия посмотрите сюда, - усовершенствовать базу данных: не оставляя её просо открытым массивом.
- стилизовать все это.
Ещё момент
Написано с поддержкой JSDoc, но если оно мешает, я уберу со скриптов.