无法读取属性“”;name”;的未定义

Cannot read property "name" of undefined

本文关键字:name 未定义 读取 属性      更新时间:2023-09-26

我有一个奇怪的"bug"(引用是因为它没有破坏任何东西,只是控制台中的一个错误)。

我有一个模拟零售网站的网站。当您点击一个项目时,会弹出一个div,询问您是否要将其添加到购物车中。如果您按下confirm,它会将产品名称和价格发送到一个函数,该函数会将其添加到EasyUI数据网格中,如下所示:

检查产品是否被点击:

$(document).on('click', '.item', function() {
        if (ismobile) {
            price = $(this).find('p.title').attr("data");
            name = $(this).find('p.title').html();
            image = $(this).find('img').attr("src");            
            mobileproducts(price, name, image);
        }
    });

检查是否点击了"添加到购物车":

$(document).on('click', "#mob_add", function() {
        name = $(".mob_title").html();
        //price = $(".mob_price").html();
        addProduct(name, parseFloat(price));
        console.log(name + parseFloat(price));
        $("#popup").hide();
    });

以及将其添加到Datagrid(购物车)中的函数。

function addProduct(name, price) {
    function add(){
        for (var i=0; i<data.total; i++) {
            var row = data.rows[i];
            if(row.name == name) {             ** ERROR HAPPENS ON THIS LINE **
                row.quantity++;
                return;
            }
        }
        data.total++;
        data.rows.push({
            name:name,
            quantity:1,
            price:price
        });
    }
    add();
    ...
}

现在,正如我所提到的,这非常好,没有问题。商品会添加到购物车中,如果有多个商品,则商品数量会增加。如果您将产品拖动到购物车中而不是单击它,则也可以正常工作,打印时不会出现错误。

这里可以看到一个演示:(注意,要点击产品,窗口必须<900px宽,拖放需要窗口>900px)

我想知道的是,为什么会发生这种错误。

编辑:我还发现,当您第一次加载页面并添加产品时,不会打印任何错误,但之后添加产品会导致错误。如果您重新加载页面,打开产品对话框,关闭它而不添加到购物车中,然后将任何产品添加到购物篮中,也会发生这种情况。

在给出有用的评论和必要的否决票后,我再次查看了调试器。使用对话框似乎会导致对产品进行一次额外的迭代(最后一行未定义)。

您可能正在调用add()函数两次。

更新:

使用firefox,我将网页(使用complete)临时保存在本地驱动器上。

我注意到处理add的点击事件的函数(在对话框中)显示了我的警报test两次,而不是一次。

$(document).on('click', "#mob_add", function() {
        name = $(".mob_title").html();
        //price = $(".mob_price").html();
    alert("TEST"); // Should run only once
    addProduct(name, parseFloat(price));
    console.log(name + parseFloat(price));
    $("#popup").hide();
});

更新:您正在重新使用相同的对话框,并使用选择器不断向document对象重新添加新的单击处理程序。

如果每次出现对话框时都调用mobileproducts,则每次都会绑定一个额外的单击处理程序。

    function mobileproducts(price, name, image) {
        $("#popup").show();
        $(".mob_title").html(name);
        $("#popup > img").attr("src", image);
        $(".mob_price").html("£" + price);

        $(document).on('click', "#mob_close", function() {
                $("#popup").hide();

    });
     alert('binding again');
        $(document).on('click', "#mob_add", function() {
            name = $(".mob_title").html();
        //price = $(".mob_price").html();
        alert("TEST");
        addProduct(name, parseFloat(price));
        console.log(na
me + parseFloat(price));
            $("#popup").hide();
        });
        console.log("CLICKED: " + name + " WITH PRICE: " + price + " AND IMAGE URL: " + image);
    }

修复

最快的解决方法是先停止绑定文档,然后切换到使用弹出窗口(甚至按钮)。此外,在找到新函数之前,您应该解除前一个函数的绑定。

下面的工作示例:

function mobileproducts(price, name, image) {
    $("#popup").show();
    $(".mob_title").html(name);
    $("#popup > img").attr("src", image);
    $(".mob_price").html("£" + price);
    //alert("TEST2");
    $("#popup").unbind('click');
    $("#popup").on('click', "#mob_close", function() {
        $("#popup").hide();
    });
    $("#popup").on('click', "#mob_add", function() {
        name = $(".mob_title").html();
        //price = $(".mob_price").html();

        addProduct(name, parseFloat(price));
        console.log(name + parseFloat(price));
        $("#popup").hide();
    });
    console.log("CLICKED: " + name + " WITH PRICE: " + price + " AND IMAGE URL: " + image);
}

一个更好的解决方案是使用on甚至只进行一次BIND,并重构代码以使用该函数可用的单例参数。