Files
webprogrammierung/js/comments.js
T
2026-06-15 22:32:00 +02:00

151 lines
4.4 KiB
JavaScript

/**
* Initialisiert die Kommentarfunktion.
*
* Ermöglicht:
* - Erstellen neuer Kommentare
* - Antworten auf bestehende Kommentare
* - AJAX-Kommunikation ohne Seitenneuladen
*/
document.addEventListener("DOMContentLoaded", function () {
const form = document.getElementById("comment-form");
const commentsList = document.getElementById("comments-list");
const commentContent = document.getElementById("comment-content");
const parentCommentInput = document.getElementById("parent-comment-id");
const replyInfo = document.getElementById("reply-info");
if (!form || !commentsList || !commentContent || !parentCommentInput || !replyInfo) {
return;
}
/**
* Registriert die Antwort-Buttons.
*
* Beim Klick wird die ID des Eltern-Kommentars gespeichert,
* damit die neue Nachricht als Antwort angelegt werden kann.
*/
document.querySelectorAll(".reply-button").forEach(function (button) {
button.addEventListener("click", function () {
parentCommentInput.value = button.dataset.commentId;
replyInfo.textContent =
"Antwort auf " + button.dataset.author;
replyInfo.style.display = "block";
commentContent.focus();
});
});
/**
* Verarbeitet das Absenden eines Kommentars.
*
* Die Daten werden per AJAX an den Server gesendet,
* sodass die Seite nicht neu geladen werden muss.
*/
form.addEventListener("submit", function (event) {
event.preventDefault();
const formData = new FormData(form);
const parentCommentId = parentCommentInput.value;
/*
* Sendet den Kommentar an den Server
* und speichert ihn in der Datenbank.
*/
fetch("php/ajax/add-comment.php", {
method: "POST",
body: formData
})
.then(response => response.json())
.then(data => {
if (!data.success) {
alert(data.message);
return;
}
const emptyMessage =
commentsList.querySelector(".no-comments-message");
if (emptyMessage) {
emptyMessage.remove();
}
const commentElement =
document.createElement("div");
commentElement.classList.add("comment-item");
if (parentCommentId) {
commentElement.classList.add("comment-reply");
}
commentElement.innerHTML = `
<p>
<strong>${escapeHtml(data.author)}</strong>
<span>${escapeHtml(data.created)}</span>
</p>
<p>${escapeHtml(data.content).replace(/\n/g, "<br>")}</p>
`;
/*
* Antworten werden unter dem
* zugehörigen Kommentar angezeigt.
*/
if (parentCommentId) {
const parentComment = document.querySelector(
`.comment-item[data-comment-id="${parentCommentId}"] .comment-replies`
);
if (parentComment) {
parentComment.appendChild(commentElement);
}
} else {
/*
* Normale Kommentare werden
* oben in die Liste eingefügt.
*/
commentElement.dataset.commentId = "";
commentsList.prepend(commentElement);
}
/*
* Formular zurücksetzen.
*/
commentContent.value = "";
parentCommentInput.value = "";
replyInfo.textContent = "";
replyInfo.style.display = "none";
})
.catch(() => {
alert(
"Kommentar konnte nicht gesendet werden."
);
});
});
/**
* Escaped HTML-Sonderzeichen zur Vermeidung
* von XSS-Angriffen.
*
* @param {string} text Zu bereinigender Text
* @returns {string} HTML-sicherer Text
*/
function escapeHtml(text) {
const div = document.createElement("div");
div.textContent = text;
return div.innerHTML;
}
});