JavaScript增加按钮仅增加一次 [英] JavaScript increase button increases only once

查看:88
本文介绍了JavaScript增加按钮仅增加一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是JS的初学者,并且在购物车中工作.我有几种产品使用ES6模板字符串在页面中呈现.到目前为止,一切正常,您可以将项目添加到购物篮中,并且购物篮和总更新正确.我唯一遇到麻烦的部分是增加/减少按钮:它们只能工作一次,如果再次单击,控制台中打印的数量将保持不变.

I am a beginner in JS and working at a shopping cart. I have several products which are rendered in the page with ES6 template strings. Everything is working so far, you can add items to the basket and the basket and total update correctly. The only part I am having trouble with is the increase/decrease buttons: they only work once, if you click again the amount printed in the console stays the same.

我确实找到了其他与增量/减量功能相关的SO帖子,但是该按钮仅保持工作一次,因此我认为问题与我忽略的代码中的其他内容有关.

I did find other SO post related to increment/decrement functions but the button keeps working only once, so I reckon the problem is related to something else in the code that I am overlooking.

请参见下面的代码:

这是将要呈现的购物车

// select ul
const shoppingCart = document.querySelector('.cart-items');

// create a li item inside ul
let billContainer = document.createElement('li');

// attach an event listener to every  li
billContainer.classList.add('list');

// create the markup for every item added to the cart
for(let j = 0; j < basket.length; j++){

    const billMarkup =  `
                <p class="prodName">${basket[j].name}</p>
                <div class="button-wrapper">
                    <button type="button" name="increase" class="increase">+</button>
                    <span class="quantity">${basket[j].quantity}</span>
                    <button type="button" name="decrease" class="decrease">-</button>
                </div>
                <p class="totPrice">£${basket[j].price}</p>
        `;

    // add the markup to the DOM
    billContainer.innerHTML = billMarkup;
    shoppingCart.appendChild(billContainer);
}

这是增加/减少功能(按钮的事件侦听器附加到其父级"li"):

and this is the increase/decrease functionality (the event listener for the buttons is attached to their parent 'li'):

// attach an event listener to every li
const li = document.querySelectorAll('.list');
li.forEach( liItem => liItem.addEventListener('click', updateBill));

// add or remove items on click
function updateBill(e){
    if(e.target.nodeName === 'BUTTON'){

    // current value in the basket
    let value = parseInt(this.querySelector('.quantity').textContent);

    // if the user clicks on 'increase' button
    if(e.target.name === 'increase'){
        value++;
        console.log(value);

    // if the user clicks on 'decrease' button
    } else if(e.target.name === 'decrease'){

         value < 1 ? value = 1 : '';
         value--;
         console.log(value);
        }
    }
}

谢谢!

推荐答案

问题

加号/减号按钮inc/减小一次,则不会再走了.

Problem

Plus/minus buttons inc/decremented only once then wouldn't go any further.

值更改后,它只是控制台中浮动变量中的一个数字,因为这是与该值有任何关系的最后一条语句.因此,只有初始更改成功,但是第二次单击按钮时,该功能返回到span.quantity并获得从上次单击以来从未更新过的值.

Once a value has changed, it is just a number in a variable floating in the console since that is the last statement that has anything to do with the value. So only the initial change is successful but when the buttons are clicked for the second time, the function goes back to span.quantity and gets the value that's never been updated from the last click.

解决当前问题的最简单方法是更新span.quantity的值:

The easiest way to resolve the problem at hand is to update the value of span.quantity:

if (e.target.name === 'increase') {
    value++;
    console.log(value);
} else if (e.target.name === 'decrease') {
    value--;
    value = value < 1 ? 1 : value;
    console.log(value);
} else {
    return false;
}

this.querySelector('.quantity').textContent = value;

因为您没有提供功能或可复制的演示,所以我没有费心去测试它,也没有试图现场检查您的代码.重写源代码并解决问题,甚至可以防止将来出现问题的工作量较小.


Because you didn't provide a functional nor a copyable demo, I didn't bother to test it nor did I attempt to spot check your code. It's less effort to rewrite the source and resolve the problem and maybe prevent problems in the future.


该演示使用不同的API来引用表单控件以及替代方法和属性,这些替代方法和属性是较常用的更好的版本.使用事件委托.数组方法可能已经过时了,但是我喜欢使用它们.以下是对演示的订单项引用,很遗憾,堆栈代码段没有行号. 柱塞-index.html和README.md 可以一起阅读带有行号.

The Demo uses a different API for referencing form controls and alternate methods and properties that are better versions of ones that are more commonly used. Event Delegation is used. Array methods might've been overkill but I like using them. Below are line item references to the Demo, unfortunately Stack Snippets don't have line numbers. The Plunker - index.html and README.md can be read together with line numbers.

HTMLFormControlsCollection

  • 52声明<form>

53引用所有表单控件,

53 Referencing ALL form controls,

92-95为每个表单控件创建非常简短的引用,

92-95 Create very short references to each form control,

96-99创建对其值的引用,并将其转换为数字,

96-99 Create references to their values and convert them to numbers,

102-103、109-110简单和短表达式

102-103, 109-110 Simple and short expressions,

122总价值

模板文字

  • 75-83通过使用语义元素改进了列表项的布局.每个元素都分配有一个唯一的#id,

  • 75-83 Improved the layout for the list items by using semantic elements. Each element is assigned a unique #id,

92-94灵活引用源自89和90结果的#id.

92-94 Flexible referencing of #ids originating from the results of 89 and 90.

数组方法

  • 90-91 By planning a specific naming strategy: abc-0, split('-').pop() returns the number end of an id and split('-').shift() returns the letters before the dash,

113-120收集所有.prc map() 返回价格总计数组; reduce() 返回总和;

113-120 Collecting all .prc; map() returns an array of price totals; reduce() returns the total sum;

事件委托/事件对象

  • 52引用<form>

54注册<form>以单击事件.这是唯一需要的EventListener,它将适用于其所有子代/后代,

54 Register the <form> to click events. This is the only EventListener needed, it will work for all of its children/descendants,

88-91,100使用Event.target属性引用事件的原点,不仅确定单击的元素,而且还确定其他元素,例如兄弟姐妹,父母/祖先和孩子/后代.

88-91, 100 Reference origin of event with the Event.target property and not only determine the clicked element but others as well like siblings, parents/ancestors, and children/descendants.

其他

  • 56-71看起来basket是对象数组吗?在OP中没有看到它,所以我不得不猜测.删除了basket[j].quantity属性,因为每个项目最初的数量为1更为有意义.

  • 56-71 It looks like the basket is an array of objects? Didn't see it in the OP so I had to guess. Removed the basket[j].quantity property because it makes more sense that each item is initially a quantity of 1.

84 insertAdjacentHTML() 在类固醇上是innerHTML.

84 insertAdjacentHTML() is innerHTML on steroids.

<!DOCTYPE html>
<html>

<head>
  <style>
    html,
    body {
      font: 400 16px/1.1 Consolas;
    }
    
    legend {
      font-size: 1.3rem;
    }
    
    output,
    input {
      display: inline-block;
      text-align: center;
    }
    
    [id^=qty] {
      width: 1.5ch;
    }
    
    [id^=prc] {
      min-width: 9ch;
    }
    
    [id^=prc]::before {
      content: "= £";
    }
    
    [id^=bas]::before {
      content: " x  £";
    }
    
    #cart+label {
      display: inline-block;
      margin: 10px 0 0 40%;
    }
    
    #total::before {
      content: " £";
    }
  </style>
</head>

<body>
  <form id='cart'></form>
  <label>Total:
    <output id='total' form='cart'>0.00</output>
  </label>
  <script>
    var cart = document.forms.cart;
    var x = cart.elements;
    cart.addEventListener('click', updateBill, false);

    var basket = [{
      name: "thing0",
      price: 1.99
    }, {
      name: "thing1",
      price: 12.99
    }, {
      name: "thing2",
      price: 21.59
    }, {
      name: "thing3",
      price: 0.09
    }, {
      name: "thing4",
      price: 5.99
    }];

    for (let j = 0; j < basket.length; j++) {
      var details = `
      <fieldset id="item-${j}">
        <legend>${basket[j].name}</legend>
        <button id="inc-${j}" type="button">+</button>
        <output id="qty-${j}">1</output>
        <button id="dec-${j}" type="button">-</button>
        <output id="bas-${j}">${basket[j].price}</output>
        <output id="prc-${j}" class="prc">${basket[j].price}</output>
    </fieldset>
    `;
      cart.insertAdjacentHTML('beforeend', details);
    }

    function updateBill(e) {
      if (e.target.type === 'button') {
        var ID = e.target.parentElement.id;
        var idx = ID.split('-').pop();
        var dir = e.target.id.split('-').shift();
        var qty = x.namedItem(`qty-${idx}`);
        var bas = x.namedItem(`bas-${idx}`);
        var prc = x.namedItem(`prc-${idx}`);
        var sum = x.total;
        var quantity = parseInt(qty.value, 10);
        var base = parseFloat(bas.value).toFixed(2);
        var price = parseFloat(prc.value).toFixed(2);
        var total = parseFloat(sum.value).toFixed(2);
        if (dir === "inc") {
          quantity++;
          qty.value = quantity;
          prc.value = quantity * base;
        } else {
          quantity--;
          if (quantity <= 0) {
            quantity = 1;
          }
          qty.value = quantity;
          prc.value = quantity * base;
        }
      }
      var prices = Array.from(document.querySelectorAll('.prc'));

      var numbers = prices.map(function(dig, idx) {
        return parseFloat(dig.value);
      });
      var grandTotal = numbers.reduce(function(acc, cur) {
        return acc + cur;
      }, 0);

      x.total.value = grandTotal.toFixed(2);
    }
  </script>
</body>

</html>

这篇关于JavaScript增加按钮仅增加一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆