0

如何填充包含一些 css 属性的 JSON 对象。我需要在哪里将所有未包含的属性添加到前一个对象,并且为所有下一个项目添加相同的属性?

我需要的声明:

if (property is not in object) object[property] = $('.foo').css(property);

例如,我们有一个具有以下样式的元素:

.foo {
    top: 0;
    width: 100px;
}

以及以下keyframe类似对象:

var keyframe = {
    0: {
        top: 0
    },
    1000: {
        top: 100
    },
    2000: {
        width: 100
    }
};

在这里,我们需要填充所有以前的项目,在这种情况下:

  • 0: width = 0
  • 1000: width = 0

...我们得到这样的东西:

var keyframe = {
    0: {
        top: 0,
        width: 0
    },
    1000: {
        top: 100,
        width: 0
    },
    2000: {
        top: 100,
        width: 100
    }
};

...此外,我们需要预先填写所有下一项:

  • 2000: top = 100

结果是什么:

var keyframe = {
    0: {
        top: 0
    },
    1000: {
        top: 100
    },
    2000: {
        top: 100,
        width: 100
    }
};

我们的最终对象需要是这样的:

var keyframe = {
    0: {
        top: 0,
        width: 0
    },
    1000: {
        top: 100,
        width: 0
    },
    2000: {
        top: 100,
        width: 100
    }
};

更新

到目前为止,TJ Crowder 的答案看起来不错,但问题是我不知道keyframe-object 中有哪些属性...所以它可以是,关键帧中有更多/其他属性而不是widthtop

更新2

目前我有以下内容:

var $foo = $('.foo');
for (var key in keyframe) {
    var obj = keyframe[key];
    for(var ok in obj) {
        if (!(ok in obj)) obj[ok] = $foo.css(ok);
    }
}

似乎

if (!(ok in obj)) // is always `truthy`

但是,如果我通过直接声明来做到这一点

if (!('top' in obj)) // it works...

有任何想法吗?

4

2 回答 2

1

两个想法:

  1. 使用原型创建关键帧对象,例如:

    var proto = {top: 0, width: 100};
    var keyframe = {
        0:    Object.create(proto),  // Inherits everything
        1000: Object.create(proto, { // Inherits only width
                  top: {value: 100}
              },
        2000: Object.create(proto, { // Inherits only top
                  width: {value: 100}
              })
    };
    
  2. 使用 for-in( spec , article ) 和in( spec ) 手动执行:

    var obj, key;
    for (key in keyframe) {
        obj = keyframe[key];
        if (!('top' in obj)) {
            obj.top = 0;
        }
        if (!('width' in obj)) {
            obj.width = 100;
        }
    }
    

    for-in循环遍历对象的可枚举属性的名称。in检查对象是否为具有给定名称的属性(它自己的,或者在它的原型上)。在上面,我假设其中的对象keyframe继承属性是可以的。

    如果你的关键帧对象都是从其他对象派生的(例如,它们有其他东西而不是Object.prototype原型),你会想hasOwnProperty在那里扔一个:

    var obj, key;
    for (key in keyframe) {
        if (keyframe.hasOwnProperty(key)) {
            obj = keyframe[key];
            if (!('top' in obj)) {
                obj.top = 0;
            }
            if (!('width' in obj)) {
                obj.width = 100;
            }
        }
    }
    
于 2013-07-16T13:07:12.970 回答
1

这似乎可以满足您的要求:

var all = {};

$.each(keyframe, function(_, obj) {
    $.each(obj, function(k) {
        all[k] = 0;
    });
});

$.each(keyframe, function(_, obj) {
    $.each(all, function(k) {
        if(k in obj)
            all[k] = obj[k];
        else
            obj[k] = all[k];
    });
});

console.log(keyframe)
// {"0":{"top":0,"width":0},
// "1000":{"top":100,"width":0},
// "2000":{"width":100,"top":100}}
于 2013-07-16T14:12:55.483 回答