Jonas Grumann Jonas Grumann - 12 days ago 7
Javascript Question

Setting background gradient with jquery - jshint error

I'm trying to animate a background gradient with jQuery, like this:

this.$next.css('line-indent', 0).animate({
'line-indent': 100
}, {
"duration": 750,
"step": function(value) {
$(this).css({
"background": color,
"background": "moz-radial-gradient (50% 50%, ellipse cover, transparent " + value + "%, " + color + " " + value + "%))",
"background": "-webkit-radial-gradient(50% 50%, circle, transparent " + value + "%, " + color + " " + value + "%)",
"background": "radial-gradient(circle at center, transparent " + value + "%, " + color + " " + value + "%)"
})
},
"easing": 'easeInQuint',
"complete": function() {
$(this).css({
"transition": 'none',
"background": color,
"background": "moz-radial-gradient (50% 50%, ellipse cover, transparent 0%, " + color + " 0%)",
"background": "-webkit-radial-gradient(50% 50%, circle, transparent 0%, " + color + " 0%)",
"background": "radial-gradient(circle at center, transparent 0%, " + color + " 0%)",
"width": 0
})
self.$loader.fadeIn(0);
}
});


This works exactly the way I want, except, when I try to build the dist files for production, jshint throws a
duplicate key
error for the
background
property, which makes sense. my question is, how to I prevent this error while setting the background gradient for all the different browsers?

Answer

jsHint is correct as your code is flawed. You're overwriting the background key each time you define it in the object, so only the final value will be assigned. I can only assume it works for you as radial-gradient works in the browser you test with.

Here's a demo of the problem you have:

var foo = function(o) {
    Object.keys(o).forEach(function(key) {
        console.log(key); // note only 1 key is shown as it's overwritten
    })
    
    console.log(o.background); // shows the last value
}

foo({
    "background": 'red',
    "background": "moz-radial-gradient (50% 50%, ellipse cover, transparent 100%, red 5%))",
    "background": "-webkit-radial-gradient(50% 50%, circle, transparent 100%, red 5%)",
    "background": "radial-gradient(circle at center, transparent 100%, red 5%)"
})

To fix this you need to call attr() and apply the style directly to the element. css() can't be used as it will also overwrite the background property each time you call it.

var style = [
    "background: " + color,
    "background: moz-radial-gradient (50% 50%, ellipse cover, transparent " + value + "%, " + color + " " + value + "%))",
    "background: -webkit-radial-gradient(50% 50%, circle, transparent " + value + "%, " + color + " " + value + "%)",
    "background: radial-gradient(circle at center, transparent " + value + "%, " + color + " " + value + "%)"
].join(';');

$(this).attr('style', style); 

I admit it's ugly, but there's no real alternative