#javascript #fetch #fetch-api
Вопрос:
Я пытаюсь сделать возможным комментировать на сайте. Если я опубликую первый комментарий, он будет опубликован нормально. При публикации второго, fetch отправляет 2 запроса и отображает один и тот же комментарий 2 раза, третий комментарий запрашивает 3 и отображает 3 раза и т. Д. Что мне нужно сделать, чтобы все работало?
JS
function insertNewComment(data) {
var ul = document.getElementById("new-comment");
ul.insertAdjacentHTML('afterBegin', '<li class="list-group-item">' data.text '</li>');
}
function sendComment() {
document.getElementById('comment').addEventListener('submit', (e) => {
e.preventDefault();
const formData = new FormData(e.target);
fetch(e.target.getAttribute('action'), {
method: e.target.getAttribute('method'),
body: formData
})
.then((response) => {
return response.json();
})
.then((data) => {
insertNewComment(data);
document.getElementById('comment').reset();
});
});
}
HTML
{% extends 'base.html' %}
{% block other_resources %}
<link rel="stylesheet" href="{{ url_for('.static', filename='css/post.css') }}">
<script src="{{ url_for('.static', filename='js/post.js') }}"></script>
{% endblock %}
{% block content %}
<div class="card">
<img src="{{ post.photo_path }}" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">{{ post.title }}</h5>
<p class="card-text">{{ post.text }}</p>
<p class="card-text"><small class="text-muted">{{ post.created }}</small></p>
<div class="card-header">
Написать комментарий:
</div>
<div>
<form action="{{ url_for('news.add_comment', post_id=post.id) }}" id='comment' method="POST">
{{form.csrf_token}}
<div class="form-floating">
{{form.text(class='form-control')}}
{{form.text.label(for="floatingTextarea2")}}
</div>
{{form.submit(class="btn btn-dark send-comment", onclick='sendComment()')}}
<div class="form-floating">
<label for="floatingTextarea2">Комментарий</label>
</div>
</form>
</div>
<div class="card comments">
<div class="card-header">
Комментарии:
</div>
<ul class="list-group list-group-flush" id='new-comment'>
{% for c in comments %}
<li class="list-group-item">{{ c.text }}</li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% endblock %}
Ответ №1:
Каждый раз, когда вы выполняете sendComment
, вы добавляете к этому еще submit
одного слушателя form
.
Убедитесь, что вы добавили только одного слушателя:
function sendComment(e) {
e.preventDefault();
const formData = new FormData(e.target);
fetch(e.target.getAttribute('action'), {
method: e.target.getAttribute('method'),
body: formData
})
.then((response) => {
return response.json();
})
.then((data) => {
insertNewComment(data);
document.getElementById('comment').reset();
});
};
// add the listener outside of `sendComment`
document.getElementById('comment').addEventListener('submit', sendComment);