#javascript #html #json #flask
#javascript #HTML #json #колба
Вопрос:
Я пытаюсь получить идентификатор, присвоенный этим html-кнопкам, но когда я читаю значение до того, как оно выдает мне правильное значение, но когда я нахожусь в реализации функции, оно всегда считывает значение 1.
Следуя фрагменту html:
<section class="section-products">
<div class="products">
{% for d in data %}
<div class="container">
{{d.name}}
<div class="descriptionProduct">
{{d.description}}
<div class="quantityProduct">
<button class="productButton" title="add to cart">add to cart</button>
<div class="modal">
<div class="modal-content">
<span class="close-button">amp;times;</span>
<h2>Choose the desired quantity: </h2>
<input type="number" id="numOfProduct" min="1" max="3">
<button class="confirmButton" data-id="{{ d.id }}"> Confirm </button>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</section>
и ниже приведен фрагмент Javascript:
let confirmButtons = document.querySelectorAll(".confirmButton");
for(let i=0; i<confirmButtons.length; i ){
console.log(confirmButtons[i].dataset['id']);
confirmButtons[i].onclick = (e) => {
const idproduct = e.target.dataset['id'];
console.log(idproduct);
В первой консоли.в журнале все так, как и должно быть, но при второй попытке считывания значения он всегда считывает одно и то же значение — 1.
Я действительно не знаю, как это исправить, потому что, когда я запускаю код, ошибки нет, он просто работает не так, как я ожидал.
РЕДАКТИРОВАТЬ: Мой HTML-код прямо сейчас редактируется следующим образом:
<button type="button" class="confirmButton" data-idproduct="{{ d.idproduct }}" > Confirm </button>
и Javascript, подобный этому:
function addProduct(ev) {
const id = ev.currentTarget.dataset['idproduct'];
console.log(ev);
fetch('/shop/add', {
method: 'POST',
body: JSON.stringify({
'mail': 'none',
'idproduct' : id
}),
headers: {
'Content-Type': 'application/json'
}
}).then(function (response) {
return response.json();
}).then(function (jsonResponse) {
console.log(jsonResponse);
});
}
let confirmButtons = document.querySelectorAll(" .confirmButton");
confirmButtons.forEach(el => el.addEventListener("click", addProduct));
И это все равно дает мне значение 1, несмотря ни на что. Ниже приведено изображение консоли из Chrome
Комментарии:
1. Не помещайте функции внутри циклов
2. Не создавайте повторяющиеся идентификаторы. Никогда не используйте / не создавайте одинаковые повторяющиеся идентификаторы внутри циклов for .
3. Никогда не используйте
Event.target
(если вы действительно не знаете, что делаете) ИспользуйтеEvent.currentTarget
вместо этого.4. Проблема связана с атрибутом data-id, а не с атрибутом id. Но Роко С. прав, у вас никогда не должно быть дублированных идентификаторов.
Ответ №1:
Ваш код действительно работает. Я думаю, что ваше значение идентификатора данных неверно в DOM, поэтому каждый раз консоль регистрирует ‘1’.
Или, может быть, вам следует быть более конкретным при выборе кнопки подтверждения здесь: document.querySelectorAll(".confirmButton");
Потому что, возможно, где-то на вашей странице, которую вы выбираете, есть другой .confirmButton .confirmb . Вы могли бы попробовать:
document.querySelectorAll(".section-products .descriptionProduct .confirmButton");
Вот пример с вашим кодом, показывающий, что он работает:
let confirmButtons = document.querySelectorAll(".confirmButton");
for(let i=0; i<confirmButtons.length; i ){
console.log(confirmButtons[i].dataset['id']);
confirmButtons[i].onclick = (e) => {
const idproduct = e.target.dataset['id'];
console.log({idproduct});
}
}
<section class="section-products">
<div class="products">
<div class="container">
hello
<div class="descriptionProduct">
description
<div class="quantityProduct">
<button class="productButton" title="add to cart">add to cart</button>
<div class="modal">
<div class="modal-content">
<span class="close-button">amp;times;</span>
<h2>Choose the desired quantity: </h2>
<input type="number" id="numOfProduct" min="1" max="3">
<button class="confirmButton" data-id="0"> Confirm </button>
</div>
</div>
</div>
</div>
</div>
<div class="container">
hello
<div class="descriptionProduct">
description
<div class="quantityProduct">
<button class="productButton" title="add to cart">add to cart</button>
<div class="modal">
<div class="modal-content">
<span class="close-button">amp;times;</span>
<h2>Choose the desired quantity: </h2>
<input type="number" id="numOfProduct" min="1" max="3">
<button class="confirmButton" data-id="1"> Confirm </button>
</div>
</div>
</div>
</div>
</div>
<div class="container">
hello
<div class="descriptionProduct">
description
<div class="quantityProduct">
<button class="productButton" title="add to cart">add to cart</button>
<div class="modal">
<div class="modal-content">
<span class="close-button">amp;times;</span>
<h2>Choose the desired quantity: </h2>
<input type="number" id="numOfProduct" min="1" max="3">
<button class="confirmButton" data-id="2"> Confirm </button>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
Комментарии:
1. В первой консоли. регистрируйте, что он печатает правильные значения. данные не пустые.
2. Я отредактировал свой пост, сказав, что, возможно, вы могли бы попытаться быть более конкретными со своими селекторами. Мы не можем помочь вам больше, чем это, поскольку у нас нет доступа ко всей вашей кодовой базе. Как вы можете видеть, ваш JS и Html-код верны. Проблема в другом месте. Возможно, моя рекомендация (после моего редактирования) может быть вашим решением. Надеюсь, это поможет 😉
Ответ №2:
- Не помещайте функции внутри циклов
- Кнопка должна быть
type="button"
(в противном случае по умолчанию type"submit"
) - Не создавайте дублирующиеся идентификаторы. Никогда не используйте / не создавайте одни и те же повторяющиеся идентификаторы, например, внутри механизма шаблонов для циклов.
- Никогда не используйте Event.target (если вы действительно не знаете, что делаете) Вместо этого используйте Event.currentTarget * .
Чем вот некоторые незначительные улучшения вашего кода JS:
function getProductId(ev) {
const id = ev.currentTarget.dataset.id;
console.log(id);
}
const confirmButtons = document.querySelectorAll(".section-products .confirmButton");
confirmButtons.forEach(el => el.addEventListener("click", getProductId));
* Вот лишь небольшой пример, демонстрирующий, что не следует «не использовать Event.target»
document.querySelector("button").addEventListener("click", (ev) => {
console.log(`
target: ${ev.target.dataset.id}
currentTarget: ${ev.currentTarget.dataset.id}
`);
});
.icon-lol:after { content: "1F608"; font-style: normal; }
<button type="button" data-id="101">CLICK-ME <i class="icon-lol"></i> amp;larr; or this guy</button>
Комментарии:
1. Я следовал вашим советам, но все равно работает не так, как я ожидал. Прямо сейчас мой код в js выглядит следующим образом: ` function addProduct(ev) { const id = ev.currentTarget.dataset.id ; console.log(идентификатор); … } пусть confirmButtons = document . querySelectorAll(«.section-products .confirmButton»); confirmButtons . forEach(el => el.addEventListener(«click», addProduct)); `
Ответ №3:
Я думаю, я понял, в чем на самом деле проблема в моем коде. После некоторых глубоких размышлений я предполагаю, что экземпляр класса .modal всегда ссылается на первый экземпляр. Я не знаю наверняка, связано ли это с тем, что был создан только один экземпляр или что-то в этом роде. Я не буду искать решение, я просто изменю подход, потому что то, что я должен сделать, не имеет значения, как это делается. Я благодарю всех, кто пытался мне помочь.