简体   繁体   English

当指定为仅删除一次时,拼接将从数组中删除多个项

[英]Splice is removing more that one item from array when specified to only remove once

I have created a mockup shopping basket, the quantity add's fine but the remove isn't working as it should. 我创建了一个样机购物篮,添加数量可以,但是删除不能正常工作。 I have specificed in the remove method to splice at the location and to remove only 1 entry from the array but it seems to remove them all. 我已在remove方法中指定了要在该位置进行拼接并仅从数组中删除1个条目的功能,但似乎将它们全部删除了。

To reproduce the error just 重现错误

Add 3 x Swede Add 3 x Parsnip 添加3 x瑞典人添加3 x欧洲防风草

Remove 1 x Swede 移除1 x瑞典人

You can see the code via online IDE here https://codio.com/adam91holt/305CDE-Challenge-3 您可以在此处通过在线IDE查看代码, 网址为https://codio.com/adam91holt/305CDE-Challenge-3

Here is the full JS code - the remove funtion is at the bottom 这是完整的JS代码-删除功能在底部

var shop = (function() {
    var items = [];
    var basketItems = [];
    var count = 0;
    return {
        //Constructor to create the item
        addItem: function(title, description, price) {
            this.title = title;
            this.description = description;
            this.price = price;
            this.id = count;
            this.remove = (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
            this.quantity = title
            this.html = '<tr><td>' + this.title + '</td><td>' + this.description + '</td><td>' + this.price + '</td><td><button id="' + this.id + '">Add To Basket</button></td><tr>';
            this.inBasket = '<tr id="' + this.remove + '"><td>' + this.title + '</td><td>' + this.price + '</td><td><div id="' + this.quantity + '">1</div>' + '</td><td><button id="' + this.remove + '"> Remove </button><tr>';
            items.push(this);
            count++;
        },
        //Sends new items to constructor
        createItems: function() {
            new this.addItem('Carrott', 'Lovely orange vegetable!', parseFloat(0.50).toFixed(2));
            new this.addItem('Potato', 'Fresh baking potato.', parseFloat(0.75).toFixed(2));
            new this.addItem('Brocolli', 'Green trees!', parseFloat(0.49).toFixed(2));
            new this.addItem('Parsnip', 'Sweet tasting.', parseFloat(0.60).toFixed(2));
            new this.addItem('Swede', 'Tasty fresh Swede.', parseFloat(1.00).toFixed(2));
            console.log(items);
            this.printHtml()
        },
        //Add's the html to the table from the item object
        printHtml: function() {
            var table = document.getElementById("output")
            items.forEach(function(item) {
                table.innerHTML += item.html;
            })
            this.listenerAdd()
        },
        //Creates a listener for adding to the basket
        listenerAdd: function() {
            items.forEach(function(item) {
                document.getElementById(item.id).addEventListener("click", function() {
                    shop.addToBasket(item)
                });
            });
        },
        //Creates a listener for removing from the basket
        listenerRemove: function() {
            basketItems.forEach(function(item) {
                document.getElementById(item.remove).addEventListener("click", function() {
                    shop.remove(item)
                });
            });
        },
        //Add's the item once the event listener has been triggered
        addToBasket: function(item) {
            basketItems.push(item);
            this.total();
            var basket = document.getElementById("basketitems");
            var quantity = document.getElementById(item.quantity);
            var howMany = this.checkQuantity(item);
            if(howMany <= 1) {
                basket.innerHTML += item.inBasket;
                this.listenerRemove();
            } else {
                quantity.innerHTML = howMany;
            }
        },
        //Checks basket to see if it is already there
        checkQuantity: function(item) {
            var searchTerm = item.title;
            var howMany = 0;
            for(var i = 0; basketItems.length > i; i++) {
                if(basketItems[i].title === searchTerm) {
                    howMany++
                }
            }
            return howMany;
        },
        //Calculates the running total
        total: function() {
            var total = 0
            basketItems.forEach(function(items) {
                var price = items.price;
                total = total + parseFloat(price);
            })
            var totalHTML = document.getElementById("total");
            totalHTML.innerHTML = '<b>Total = ' + parseFloat(total).toFixed(2) + '</b>';
        },
        //Allows you to remove items from the basket
        remove: function(item) {
            var where = basketItems.indexOf(item);
            var quantity = document.getElementById(item.quantity);
            basketItems.splice(where, 1);
            this.total()
            var howMany = this.checkQuantity(item);
            if(howMany === 0) {
                console.log(item.remove)
                var row = document.getElementById(item.remove);
                row.parentNode.removeChild(row);
            } else {
                quantity.innerHTML = howMany;
            }
        }
    }
})();

function init() {
    'use strict';
    shop.createItems()
};
//On window load call init function
window.onload = init;

So in the event listener called listenerRemove you do a for each which results in basically registering the same event to the same click 5 times if the quantity is 5. Solution is to only register event for new items only so first change is get the item into the table using document.createElemenet 因此,在名为listenerRemove的事件监听器中,您对每个事件都执行一个操作,如果数量为5,则基本上将同一事件注册到同一点击5次。解决方案是仅为新项目注册事件,因此首先进行更改是将项目放入该表使用document.createElemenet

like this: 像这样:

var tr = document.createElement('tr');

Give it your random ID 给它你的随机ID

tr.id = item.remove;

Append the text from item.inBasket 附加item.inBasket中的文本

tr.innerHTML = item.inBasket;

now append it to the table if it's new Item 现在将其添加到表格中(如果它是新商品)

basket.appendChild(tr);

Register event 注册活动

this.listenerRemove(item);

In event register do a single registration rather than a foreach 在事件注册中,只进行一次注册,而不是先进行注册

listenerRemove: function(item) {        

document.getElementById(item.remove).addEventListener("click", function() {
                shop.remove(item)
            });
    },

And the rest see in the fiddle http://jsfiddle.net/guqno66d/ 其余的请参见小提琴http://jsfiddle.net/guqno66d/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM