e.target.dataset не дает одно и то же значение дважды — Javascript

#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 всегда ссылается на первый экземпляр. Я не знаю наверняка, связано ли это с тем, что был создан только один экземпляр или что-то в этом роде. Я не буду искать решение, я просто изменю подход, потому что то, что я должен сделать, не имеет значения, как это делается. Я благодарю всех, кто пытался мне помочь.