【问题标题】:How to delete an item from an array from localstorage onclick如何从localstorage onclick中删除数组中的项目
【发布时间】:2022-01-11 19:59:22
【问题描述】:

我有以下代码。每次用户单击“添加到购物车”按钮时,它都会将信息存储在本地存储中:

let addCartItemButtons = document.getElementsByClassName('product-description-add')
for (let i = 0; i < addCartItemButtons.length; i++){
    let button = addCartItemButtons[i]
    button.addEventListener('click', addProduct)
} 

function addProduct(event) {
    let buttonClicked = event.target
    let getTitle = buttonClicked.parentElement.parentElement.parentElement.querySelector('.product-title').innerText
    let getImage = buttonClicked.parentElement.parentElement.parentElement.querySelector('.product-header img').src
    let getColor = buttonClicked.parentElement.parentElement.querySelector('.product-description-text li span').innerText
    let getSize = buttonClicked.parentElement.parentElement.querySelector('.product-description-text li select').value
    let getPrice = buttonClicked.parentElement.parentElement.querySelector('.product-description-price').innerText
    let getSpan = buttonClicked.parentElement.parentElement.querySelector('li span').getAttribute('id')

    let oldItems = JSON.parse(localStorage.getItem('newProduct')) || [];
    let newItem = {
        'title': getTitle,
        'image': getImage,
        'color': getColor,
        'size': getSize,
        'price': getPrice,
        'spanid': getSpan,
    };
    
    oldItems.push(newItem);
    localStorage.setItem('newProduct', JSON.stringify(oldItems));
}

然后,我有一个代码,允许我通过创建 div 并显示信息来显示用户在本地存储的数据:

let cartProducts = JSON.parse(localStorage.getItem("newProduct"))
for(let i = 0; i < cartProducts.length; i++){
    let newCartProduct = document.createElement('div')
    newCartProduct.classList.add('product')
    newCartProduct.classList.add('cart')
    const image = cartProducts[i].image
    const title = cartProducts[i].title
    const spanid = cartProducts[i].spanid
    const color = cartProducts[i].color
    const size = cartProducts[i].size
    const price = cartProducts[i].price
    let newCartProductContent = `
    <div class="product-header cart"><img src="${image}" alt="" /></div>
        <div class="product-content">
            <h3 class="product-title" id="product-title">
            ${title} 
            </h3>
            <div class="product-description">
                <ul class="product-description-text cart">
                    <li>Color: <span id="${spanid}">${color} </span></li>
                    <li>Size: ${size} </li>
                    <li>Quantity: <input type="number" class="product-description-quantity" min="1" placeholder="2" value="2"></li>
                </ul>
                <p class="product-description-price" id="price1">
                ${price} 
                </p>
                **<a href="#" class="product-description-add cart-remove">Remove<i class="fas fa-trash"></i></a>**
            </div>
        </div>`
    newCartProduct.innerHTML = newCartProductContent
    let cartItems = document.getElementsByClassName('products_container_first-row')[0]
    cartItems.append(newCartProduct)
}

所以我现在需要做的是创建一个函数,允许我删除本地存储中相同的数据,每次用户单击“删除”按钮时(在上面的代码中是在开头和结尾都有 ** ** 的行),但我不知道该怎么做。有任何想法吗?谢谢!

更新:我来到了这段代码,但我得到 -1 作为每个元素的索引:

let addCartItemButtons = document.getElementsByClassName('product-description-add')
for (let i = 0; i < addCartItemButtons.length; i++){
    let button = addCartItemButtons[i]
    button.addEventListener('click', function(event){
        let buttonClicked = event.target
        let getTitle = buttonClicked.parentElement.parentElement.parentElement.querySelector('.product-title').innerText
        let getImage = buttonClicked.parentElement.parentElement.parentElement.querySelector('.product-header img').src
        console.log(getImage)
        let getColor = buttonClicked.parentElement.parentElement.querySelector('.product-description-text li span').innerText
        let getSize = buttonClicked.parentElement.parentElement.querySelector('.product-description-text li select').value
        let getPrice = buttonClicked.parentElement.parentElement.querySelector('.product-description-price').innerText
        let getSpan = buttonClicked.parentElement.parentElement.querySelector('li span').getAttribute('id')
        console.log(getSpan)
    
        let oldItems = JSON.parse(localStorage.getItem('newProduct')) || [];
        let newItem = {
            'id': i+1,
            'title': getTitle,
            'image': getImage,
            'color': getColor,
            'size': getSize,
            'price': getPrice,
            'spanid': getSpan,
        };
        
        oldItems.push(newItem);
        localStorage.setItem('newProduct', JSON.stringify(oldItems));
    })
} 

let cartProducts = JSON.parse(localStorage.getItem("newProduct"));
for(let i = 0; i < cartProducts.length; i++){
    let newCartProduct = document.createElement('div')
    newCartProduct.classList.add('product')
    newCartProduct.classList.add('cart')
    console.log(newCartProduct)
    const id = cartProducts[i].id
    const image = cartProducts[i].image
    const title = cartProducts[i].title
    const spanid = cartProducts[i].spanid
    const color = cartProducts[i].color
    const size = cartProducts[i].size
    const price = cartProducts[i].price
    let newCartProductContent = `
    <div class="product-header cart" id="${id}"><img src="${image}" alt="" /></div>
        <div class="product-content">
            <h3 class="product-title" id="product-title">
            ${title} 
            </h3>
            <div class="product-description">
                <ul class="product-description-text cart">
                    <li>Color: <span id="${spanid}">${color} </span></li>
                    <li>Size: ${size} </li>
                    <li>Quantity: <input type="number" class="product-description-quantity" min="1" placeholder="2" value="2"></li>
                </ul>
                <p class="product-description-price">
                ${price} 
                </p>
                <a href="#" onclick="lsdel(\'newProduct\',\'+cartProducts[i].id+\');" class="product-description-add cart-remove">Remove<i class="fas fa-trash"></i></a>
            </div>
        </div>`
    newCartProduct.innerHTML = newCartProductContent
    let cartItems = document.getElementsByClassName('products_container_first-row')[0]
    cartItems.append(newCartProduct)
}
function lsdel(storage_name, value){
    if (localStorage.getItem(storage_name) === null) { 
    } else {        
        var ls_data = JSON.parse(localStorage.getItem(storage_name));
        var index   = ls_data.indexOf(value);
        console.log("selected index:"+index);
        if(index == -1){
        // if not matched selected index    
        } else {
            // is matched, remove...
            ls_data.splice(index, 1);
            localStorage.setItem(storage_name, JSON.stringify(ls_data));
            console.log(ls_data);  
        }
    }
}

【问题讨论】:

  • 从本地存储读取数组,找到与array.findIndex()匹配的元素的索引,使用array.splice()将其删除,然后将数组写回本地存储。
  • spanid是产品的ID吗?如果是这样,为什么它只在颜色周围的span标签上?
  • @Kinglish 不,spanid 是我需要存储在本地存储中的一个元素,以便我在向用户显示 div 时设置其样式,但它与产品 ID 无关
  • 感谢@Barmar,我会努力做到的
  • 您也可以将array.filter 与排除要删除的项目的谓词一起使用,然后保存过滤后的数组。

标签: javascript arrays local-storage


【解决方案1】:

value 是元素的 ID,但 ls_data 是对象数组,而不是 ID。所以ls_data.indexOf(value) 不会在数组中找到对象。即使value 是一个对象,这也行不通,因为对象相等是基于内存中相同的对象,而不是比较内容。

您需要使用findIndex 来匹配数组元素的id 属性。

function lsdel(storage_name, value) {
  if (localStorage.getItem(storage_name) === null) {} else {
    var ls_data = JSON.parse(localStorage.getItem(storage_name));
    var index = ls_data.findIndex(({id}) => id == value);
    console.log("selected index:" + index);
    if (index == -1) {
      // if not matched selected index    
    } else {
      // is matched, remove...
      ls_data.splice(index, 1);
      localStorage.setItem(storage_name, JSON.stringify(ls_data));
      console.log(ls_data);
    }
  }
}

【讨论】:

  • 感谢您的回答,但我无法使其正常工作,每次单击删除按钮时索引都会保持为“-1”。我确信您的代码可以完美运行,但问题一定是我无法识别和解决的问题:||
  • addProduct() 没有将id 放入newItem
  • 不,id 正在添加到 newItem,这是存储在 localstorage 上的数组元素的示例:0: {id: 1, title: "Adidas Hoodie", image: "http ://**/img/products/1.jpg”,颜色:“灰色”,...} 颜色:“灰色” id:1 图片:“http://**/img/products/1.jpg” 价格: "$39.99" size: "M" spanid: "sp1" title: "Adidas Hoodie" 但索引仍为 -1 :@
  • let newItem = { 'title': getTitle, 'image': getImage, 'color': getColor, 'size': getSize, 'price': getPrice, 'spanid': getSpan, }; 里面的id 在哪里?
  • 我正在查看function addProduct(event)中的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
  • 2021-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多