动态更改对象内的变量依赖于DOM

时间:2012-09-17 18:00:51

标签: javascript dom object memory

我希望有一个对象根据DOM中元素的存在返回status true / false。我无法让变量实际维护除加载页面状态之外的状态。我的最后一次尝试是相当愚蠢的,并导致Maximum call stack size exceeded,这是预期的。我可以通过DOM改变这些变量的任何方式吗?

var navigation = function runNav(){
  runNav();
  var navigation = {
    globe : {
      element : $("#icons .globe"),
      status : (function(){
        return ($(".window_stable.globe").length == 1) ? true : false;
      })()
    },
    cart : {
      element : $("#icons .cart"),
      status : (function(){
        return ($(".window_stable.cart").length == 1) ? true : false
      })()
    },
    phone : {
      element : $("#icons .phone"),
      status : (function(){
        return ($(".window_stable.phone").length == 1) ? true : false
      })()
    }
  }
  return navigation;
}();

例如

navigation.cart.status
false
-- Enabled the element
navigation.cart.status
false
($(".window_stable.cart").length == 1) ? true : false
true

3 个答案:

答案 0 :(得分:2)

您应该在代码开头删除对runNav()的调用。它导致无限递归循环。除此之外,您的代码看起来很好。

答案 1 :(得分:1)

我想我得到了你想做的事。我想您希望每次访问status属性时都为status定义的函数运行。

据我所知,我认为只要把它作为财产就可以做到。我认为你需要把它变成一个功能。

像这样:(jsFiddle

var navigation = {
    globe: {
        element: $("#icons .globe"),
        getStatus: function() { return ($(".window_stable.globe").length > 0); }
    },
    cart: {
        element: $("#icons .cart"),
        getStatus: function() { return ($(".window_stable.cart").length > 0); }
    },
    phone: {
        element: $("#icons .phone"),
        getStatus: function() { return ($(".window_stable.phone").length > 0); }
    }
};

alert("status = "+ navigation.cart.getStatus());

答案 2 :(得分:1)

您看到的问题是因为“status”属性正在立即设置。因此,如果在将这些元素添加到DOM之前初始化导航对象,则“status”将始终为false。

如果您像访问财产一样无法访问“状态”,则可以使用Object.defineProperty模式:http://jsfiddle.net/TFVFS/

var navigation = (function runNav(){
    var navigation = {
        globe : {
            element : $("#icons .globe")
        },
        cart : {
            element : $("#icons .cart")
        },
        phone : {
            element : $("#icons .phone")
        }
    };

    Object.defineProperty(navigation.globe, "status", {
        get:function(){return $(".window_stable.globe").length == 1 ? true : false;}   
    });
    Object.defineProperty(navigation.cart, "status", {
        get:function(){return $(".window_stable.cart").length == 1 ? true : false;}   
    });
    Object.defineProperty(navigation.phone, "status", {
        get:function(){return $(".window_stable.phone").length == 1 ? true : false;}   
    });
    return navigation;
})();

console.log(navigation.cart.status);
console.log(navigation.globe.status); 
console.log(navigation.phone.status);  

这不完全向后兼容,并且在版本9之前的IE中不完全支持。

@Travesty3的答案将向后兼容,但它需要更改语法。就个人而言,如果您需要在9之前支持IE版本,我会推荐他的答案。