【问题标题】:Dynamically changing variables within object dependent on DOM依赖于 DOM 的对象内动态变化的变量
【发布时间】:2012-09-17 18:00:51
【问题描述】:

我想要一个基于 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

【问题讨论】:

    标签: javascript dom object memory


    【解决方案1】:

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

    【讨论】:

    • 你确定你的选择器是正确的吗?例如,您正在寻找具有window_stablephone 类的元素?此外,您的值将根据函数最初创建的时间设置,因此如果 DOM 尚未准备好,您可能会看到 false 到处都是。
    • 我发布了控制台的输出,它显然是正确的选择器。
    • 那么您可能在 DOM 完全加载之前声明了您的函数。您的函数声明是否在 $(document).ready(function () { ... }) 内?或者至少在<body> 的底部?如果没有,您可能只是在检查元素是否存在。
    【解决方案2】:

    我想我明白你想要做什么。我认为您希望为 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());
    

    【讨论】:

      【解决方案3】:

      您看到的问题是因为“状态”属性被立即设置。因此,如果导航对象在这些元素添加到 DOM 之前被初始化,“状态”将始终为 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);  
      

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

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

      【讨论】:

        猜你喜欢
        • 2014-01-13
        • 2018-06-16
        • 2016-09-05
        • 2021-10-12
        • 2011-09-20
        • 2017-09-23
        • 1970-01-01
        • 2016-08-20
        • 2015-03-09
        相关资源
        最近更新 更多