【问题标题】:Accessing object property from function property doesn't work in Firefox从函数属性访问对象属性在 Firefox 中不起作用
【发布时间】:2012-07-19 13:11:54
【问题描述】:

下面的代码可以在 Chrome 和 IE(8) 中运行,但 firefox 说“未定义覆盖”。 使用 this.overlay 或 [this.overlay] 也不起作用。是什么导致了这种差异以及如何在 Firefox 中修复它?

代码:

var ol = {
overlay: document.getElementById("overlay"),
build: function(e){
    //todo: build elements dynamically
},
open: function(){
    overlay.style.display = "block";
    centerVertically();
    ol.build();
},
close: function(){
    overlay.style.display = "none";
}
};

提前致谢。

编辑: 解决方案独立工作(JSfiddle),但是当我在项目中使用代码时它失败了。这完全没有意义。请参阅此屏幕截图混搭: Image link

编辑 #2:

将我的脚本标签移动到 DOM 的底部修复了所有问题。我不知道为什么我没有想到这一点。这可能是从一开始的问题 - Chrome 和 IE 只是更好地处理我的愚蠢,即使有关闭问题。

但是,自从收到您的回复后,我现在编写了更安全的代码,并且知道如何正确访问对象内部的对象属性。谢谢!

【问题讨论】:

    标签: javascript function object closures


    【解决方案1】:

    就像您在引用方法时所做的那样,您只需要在引用“覆盖”时添加对象范围。

    所以在你的函数中只需执行“ol.overlay.style.display”就可以了。

    var ol = {
        overlay: document.getElementById("overlay"),
        build: function(e){
            //todo: build elements dynamically
        },
        open: function(){
            ol.overlay.style.display = "block";
            centerVertically();
            ol.build();
       },
       close: function(){
            ol.overlay.style.display = "none";
       }
    };
    ol.open();
    

    按照您现在的方式,它在“ol”对象范围之外寻找一个全局 JS 变量。

    编辑正如@Matt Ball 在下面的评论中所指(我打算添加到此)。您应该确保仅在 DOM 完成加载后才获得“覆盖”元素。

    您可以通过 document.ready 模式来做到这一点,也可以在“ol”函数中使用延迟加载模式。我建议使用 document.ready 模式并更改您的 'ol' 对象以使覆盖默认为 null 并在文档就绪时定义它(或将其放入您在文档就绪时调用的 init 类型方法中),两者都可以。

    【讨论】:

      【解决方案2】:

      这应该在所有浏览器中都可以正常工作,假设页面上有一个 ID 为 overlay 的元素:

      var ol = {
          overlay: document.getElementById("overlay"),
          build: function (e) {
              //todo: build elements dynamically
          },
          open: function () {
              this.overlay.style.display = "block";
              this.centerVertically();
              this.build();
          },
          close: function () {
              this.overlay.style.display = "none";
          },
          centerVertically: function () {
              // snip
          }
      };
      

      只要你像这样调用函数:

      ol.open();
      // or
      ol.close();
      // or
      ol.build();
      

      和不这样(这会使this在各种函数中不引用ol):

      var openFn = ol.open();
      openFn();
      // etc.
      

      【讨论】:

      • 两种解决方案似乎都可以独立工作。在这个小提琴 (jsfiddle.net/nZhsG/1) 中,我使用了这两种风格,它们都可以正常工作。但是当我在我的网页中使用它们时,即使它在我的 DOM 中,也找不到“覆盖”元素。
      • 我的钱是因为您在 DOM 准备好之前调用此代码,或者至少 <script> 标记位于网页中 ID 为 overlay 的元素之前。小提琴的 JS 在窗口加载时运行,在 DOM 准备好之后。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多