问题
How can I pre-populate an JSON-Object which contains some css-properties. Where I need to add all not-contained properties to the previous object and the same for all next up items?
The statement I need:
if (property is not in object) object[property] = $('.foo').css(property);
We have for example an element with the following styling:
.foo {
top: 0;
width: 100px;
}
And the following keyframe
-alike object:
var keyframe = {
0: {
top: 0
},
1000: {
top: 100
},
2000: {
width: 100
}
};
Here we need to populate all previous items, in this case:
0: width = 0
1000: width = 0
...we get something like this:
var keyframe = {
0: {
top: 0,
width: 0
},
1000: {
top: 100,
width: 0
},
2000: {
top: 100,
width: 100
}
};
...and further, we need to prefill all next items:
2000: top = 100
What results in:
var keyframe = {
0: {
top: 0
},
1000: {
top: 100
},
2000: {
top: 100,
width: 100
}
};
Our final object needs to be like this one:
var keyframe = {
0: {
top: 0,
width: 0
},
1000: {
top: 100,
width: 0
},
2000: {
top: 100,
width: 100
}
};
Update
T.J. Crowder answer looks good so far, however the problem is that I don't know what properties are in the keyframe
-object... So it can be, that there are more/other properties in the keyframe than width
and top
.
Update2
Currently I've the following:
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);
}
}
But it seems that
if (!(ok in obj)) // is always `truthy`
however if I do it by declaring it directly
if (!('top' in obj)) // it works...
Any ideas?
回答1:
This appears to do what you want:
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}}
回答2:
Two thoughts:
Create your keyframe objects with a prototype behind them, e.g.:
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} }) };
Do it the manual way, using
for-in
(spec, article) andin
(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
loops through the names of the enumerable properties of the object.in
checks to see if an object as a property with a given name (its own, or on its prototype). In the above, I assumed it was okay for the objects withinkeyframe
to inherit properties.If your keyframe objects are every derived from other objects (e.g., they have something other than
Object.prototype
as their prototype), you'll want to throw ahasOwnProperty
in there: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; } } }
来源:https://stackoverflow.com/questions/17677311/merge-json-object-and-populate-next-prev-items