【问题标题】:Removing specific item from localStorage从 localStorage 中删除特定项目
【发布时间】:2017-06-07 16:41:49
【问题描述】:

我正在使用 jQuery/JS 将一些项目添加到 localStorage,这一切都很好,但尝试删除数组中的特定项目(如果它是同一个项目)是困难的。

在我的控制台日志(用于测试)中,它似乎清除了 [Object],但它没有更新密钥。也许我的层次结构是错误的......有什么想法吗?

//
function addToStorage(elem, name) {

    localData = localStorage.getItem(name + 'Storage');
    var typefaces;

    if (localData == 'null' || !localData) {
        typefaces = [];
    } else {
       typefaces = JSON.parse(localData);
    }

    typefaceID = elem.find('input').val();
    typefaceName = elem.find('input').attr('data-name');
    typefacePrice = elem.find('input').attr('data-price');
    typefaceQty = 1;

    $.each(typefaces, function(index, value) {
        if (value !== null) {
            if (value.id == typefaceID) {
                if (name == 'drf') {
                    //console.log(index);
                    //console.log(typefaces);
                    typefaces.splice(index, 1);
                    //console.log(typefaces);
                }
            }
        }
    });

    typefaces.push({
        'id': typefaceID,
        'name': typefaceName,
        'price': typefacePrice,
        'qty': typefaceQty
    });

    localStorage.setItem(name + 'Storage', JSON.stringify(typefaces));

}

//
$(document).on('click', 'summary.cart td.font', function(e) {
    e.preventDefault();
    addTo = $(this);
    addTo.each(function() {
        addToStorage(addTo, 'drf');
    });
});

这是添加后的 localData 示例。

[  
   {  
      "id":"dr-raymond-desktop-40374",
      "name":"DR-Raymond",
      "format":"Desktop (OTF)",
      "price":"15.00",
      "qty":1
   },
   {  
      "id":"dr-raymond-webfont-39949",
      "name":"DR-Raymond",
      "format":"Webfont (WOFF)",
      "price":"15.00",
      "qty":1
   }
]

【问题讨论】:

  • 你能给你的 json localdata 或任何小提琴链接提供一个格式,以便它更容易解释吗?
  • @breakit 这就是它添加到原来的问题谢谢!
  • “更新密钥”是什么意思?
  • @XavierJ 如果您在检查 localStorage 时从 Chrome DevTools 中看到我的图片附件,请见谅。此实例中的“键”是 localStorage,“值”是内容(localData 数组)
  • @JohnthePainter 请检查我的回答,您的代码中还有其他错误。

标签: javascript jquery html local-storage


【解决方案1】:

在使用“foreach”对数组进行迭代时,切勿从数组中添加/删除元素。相反,试试这个:

for (index = typefaces.length - 1; index >= 0; index--){
    value = typefaces[index];
    if (value !== null) {
        if (value.id == typefaceID) {
            if (name == 'drf') {
                typefaces.splice(index, 1);
            }
        }
    }
});

另一种更优雅的方法是使用 ES6 filter():

typefaces = typefaces.filter(value => !(value && value.id == typefaceID && name == "drf"));

此外,您正在将 localData 与文字字符串 'null' 进行比较,这有点毫无意义。您的第二个条件 - if (!localData) 在这种情况下就足够了,并且会妥善处理。

【讨论】:

  • 谢谢。它仍然没有从 localStorage 中删除它。如果我单击它一次它会将其添加到 localStorage 但如果我再次单击它以删除它,它不会。
  • “删除”是什么意思?您的代码似乎总是会推送一个新项目来代替已删除的项目。
  • 是的,我刚刚解决了,哈哈!显然,我不希望它推送已删除的那个。
  • 我尝试将 push 放在 for 循环之前,但它似乎总是返回一个空数组。
  • 获取此布尔值的另一种方法是再次使用 filter():found = typefaces.filter(value => (value && value.id == typefaceID && name == "drf")).length > 0;
【解决方案2】:

问题在于您的拼接方法使用。请注意,根据MDN splice 修改数组并返回一个包含已删除元素的新数组。因此,当使用循环并尝试删除某些元素时,拼接会移动元素。这是因为通过数组增量迭代,当你拼接它时,数组被修改到位,所以项目被“移位”并且你最终跳过了一些迭代。向后循环可以解决此问题,因为您没有在拼接方向上循环。

解决方案 1

在拼接时向后循环。

for(var i = typefaces.length; i--;)
{
            if (typefaces[i] !== null) 
            {

                if (typefaces[i] == typefaceID) 
                {
                        typefaces.splice(i, 1);
                }
            }
 }

工作箱链接here.

解决方案 2

生成新数组通常比修改现有数组更快。所以,你的代码看起来像

ty = [];
   $.each(typefaces, function(index, value) {
        if (value !== null) {

            if (value.id != typefaceID) {
                    ty.push(value);
            }
        }
    });
  typefaces = ty;

工作箱链接是here。 之后,在获取和设置 localStorage 时没有发现问题。

【讨论】:

  • 执行此操作后如果您遇到有关 localStorage 的任何问题,请在此处联系我。
【解决方案3】:

你的代码中有一个额外的错误,你写

if (value !== null) {
    if (value.id == typefaceID) {
        // name will always have the value drf 
        // since you pass it in your function
        // when you call it addToStorage(addTo, 'drf');
        if (name == 'drf') {
            typefaces.splice(index, 1);
        }
    }
}

应该是什么时候

if (value !== null) {
    if (value.id == typefaceID) {
        // here the comparison should be between value.name and name
        if (value.name == name) {
            typefaces.splice(index, 1);
        }
    }
}

也可以写

if (value !== null) {
    if (value.id == typefaceID && value.name == name) {
            typefaces.splice(index, 1);
    }
}

【讨论】:

    【解决方案4】:

    你正在通过拼接来改变数组。唯一被重写的本地存储项是留在数组中的那些。

    所以当你从数组中拼接一个对象时,从存储中删除该项目。

    $.each(typefaces, function(index, value) {
            if (value !== null) {
                if (value.id == typefaceID) {
                    if (name == 'drf') {
                        //console.log(index);
                        //console.log(typefaces);
                        var removedTypeFace = typefaces.splice(index, 1);
                        //console.log(typefaces);
    
                        if(removedTypeFace) {
                            localStorage.removeItem(removedTypeFace.name + 'Storage');
                        }
                    }
                }
            }
        });
    

    【讨论】:

    • 谢谢。 'localStorage.removeItem()' 不是只删除整个密钥而不是密钥的拼接吗?
    • @JohnthePainter 你必须同时使用splice从数组中删除它,然后从本地存储中删除该属性。
    • 拼接是有道理的,但localStorage.removeItem(removedTypeFace.name + 'Storage'); 是从本地存储中删除该属性的正确方法吗?
    【解决方案5】:

    好的。你会踢自己的。第一次从 localStorage 中提取时,getItem 方法确实返回了 null 值,但您试图将其与 字符串'null',引号)进行比较。失败。我将localData == 'null' 更改为localData == null

    表达式的第二部分尝试查看从getItem 返回的值实际上是定义的,这很好。我通过typeof 将其更改为更明确。

    显式变量声明也有帮助。

    function addToStorage(elem, name) {
    
        var localData = localStorage.getItem(name + 'Storage');
        var typefaces;
    
        if (localData == null || typeof(localData) == 'undefined') {
            typefaces = [];
        } else {
           typefaces = JSON.parse(localData);
        }
    
        var typefaceID = elem.find('input').val();
        var typefaceName = elem.find('input').attr('data-name');
        var typefacePrice = elem.find('input').attr('data-price');
        var typefaceQty = 1;
    
        $.each(typefaces, function(index, value) {
            if (value !== null) {
                if (value.id == typefaceID) {
                    if (name == 'drf') {
                        //console.log(index);
                        //console.log(typefaces);
                        typefaces.splice(index, 1);
                        //console.log(typefaces);
                    }
                }
            }
        });
    
        typefaces.push({
            'id': typefaceID,
            'name': typefaceName,
            'price': typefacePrice,
            'qty': typefaceQty
        });
    
        localStorage.setItem(name + 'Storage', JSON.stringify(typefaces));
    
    }
    
    //
    jQuery(document).on('click', 'summary.cart td.font', function(e) {
        e.preventDefault();
        addTo = $(this);
        addTo.each(function() {
            addToStorage(addTo, 'drf');
        });
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <summary class='cart'><table><tr>
    <td class='font' >Click Here for Item 1
    <input data-name='abc' data-price='2.00' value="Item 1" /></td></tr>
    <tr>
    <td class='font' >Click Here for Item 2
    <input data-name='def' data-price='4.00' value="Item 2" /></td></tr></table>
    </summary>

    【讨论】:

    • 谢谢!这似乎并没有从 localStorage 中删除该项目? :(
    • 它似乎可以从数组中删除它(如果我在删除之前和之后 console.log 数组,它显示它从 [Object] 更改为 [] 但它似乎仍然存在于本地存储)。也许我的行 localStorage.setItem(name + 'Storage', JSON.stringify(typefaces)); 没有做我认为的那样......
    猜你喜欢
    • 1970-01-01
    • 2013-10-17
    • 2015-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-07
    • 1970-01-01
    相关资源
    最近更新 更多