2014-10-09 74 views
2

返回JavaScript对象的属性我只是碰到这个奇怪的问题,在IE8来了,我似乎无法找到任何关于它的更多细节。当然,如果我创建了一个JavaScript对象,但我这样做,我可以简单地通过动态定义它们添加属性:IE8无法添加的窗口

var rect = {}; 
rect.x = 200; 

大。井IE8(我不知道其他IE的),如果我叫这样的方法:“对象不支持此属性或方法”

var span = document.getElementById('my-span'); 
var rect = span.getBoundingClientRect(); 
rect.x = Math.round(rect.left); 

然后我得到的IE错误这当然不会在第一种情况下发生,我提到我在JavaScript中亲自定义了自己的对象。现在最简单的解决方法是做到这一点:

var clientRect = span.getBoundingClientRect(); 
var rect = { top: clientRect.top, left: clientRect.left, right: clientRect.right, bottom: clientRect.bottom }; 
rect.x = Math.round(rect.left); 

这没问题。但我想知道为什么是不会IE8让我动态添加字段/属性/属性(我不知道正确的JS术语)由getBoundingClientRect()方法返回此对象吗?是否有另一种(正确的)方法来添加属性?对于由window对象的方法返回的所有对象是否会发生这种情况?这是记录的吗?或者它是一个错误? (在这种情况下,我会采取解决方法并继续前进)。

+0

第一个问题:是不是只读? – ArtOfCode 2014-10-09 15:54:06

+1

答案是肯定的。 – ArtOfCode 2014-10-09 15:57:34

+0

@Bergi我想他的意思是getBoundingClientRect的'结果()'似乎是只读 – Ian 2014-10-09 16:02:17

回答

3

你的问题是在事实的getBoundingClientRect()结果是只读的。因此,你不能添加属性。但是,您可以将它们读入您自己的对象中(如您的解决方法所做的那样)。有一个稍微更简洁的方式来做到这一点:

var span = document.getElementById("span"); 
var rect = span.getBoundingClientRect(); 
var myRect = {}; 
for(var key in rect) { 
    myRect[key] = rect[key]; 
} 

这导致具有getBoundingClientRect()结果的所有属性myRect,但他们现在可读写,并且可以添加myRect.x他们。

编辑:FF和Chrome < = 37默认显示

+0

为什么IIFE?不会'myRect [key] = rect [key];'做同样的事情? – Teemu 2014-10-09 16:32:57

+0

我问了[一个问题](https://stackoverflow.com/questions/24465806/for-loop-doesnt-loop-values-of-an-object-applies-same-handler-to-each-element)关于那个不久以前。像'myRect [key] = rect [key];'这样的语句在我的'for'循环中不起作用 - 尽管我没有在这种情况下尝试过。 – ArtOfCode 2014-10-09 16:36:07

+1

那么,这里肯定会在没有IIFE的情况下工作。你的情况是不同的,因为它试图读取事件处理程序中的值,并且在调用处理程序之前更改了值。 – Teemu 2014-10-09 16:40:16

0

返回getBoundingClientRect()读写只要是明确的,它是 IE8的一个问题,并通过@Teemu更早的指出。

Object.getOwnPropertyDescriptor(window,'rect') 
// Object { configurable=false, enumerable=true, writable=true, ...} 

作为一个变通办法,为什么不把它包装在一个对象...

var rect = { 
     clntRect: span.getBoundingClientRect(), 
     x: function() { return Math.round(this.clntRect.left) }, 
     y: function() { return Math.round(this.clntRect.top) } 
    } 

或...

var rect = { 
     span: span, 
     clntRect: function() { return this.span.getBoundingClientRect() }, 
     x: function() { return Math.round(this.clntRect().left) }, 
     y: function() { return Math.round(this.clntRect().top) } 
    }