简体   繁体   中英

How can I change a CSS gradient via JavaScript?

I have a div with the following gradient applied to it:

/* Mozilla Firefox */ 
background-image: -moz-linear-gradient(top, #2E2E28 0%, #4D4C48 100%);
/* Opera */ 
background-image: -o-linear-gradient(top, #2E2E28 0%, #4D4C48 100%);
/* Webkit (Safari/Chrome 10) */ 
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #2E2E28), color-stop(1, #4D4C48));
/* Webkit (Chrome 11+) */ 
background-image: -webkit-linear-gradient(top, #2E2E28 0%, #4D4C48 100%);
/* IE10+ */
background: -ms-linear-gradient(top,  #2E2E28 0%,#4D4C48 100%);
/* W3C */
background: linear-gradient(top,  #2E2E28 0%,#4D4C48 100%);

How could I change "#2E2E28" to another number, but still avoid the cross-browser nightmare?

With jQuery it'll be :

$('.gradient').css({'background-image': 'linear-gradient(to top,  #2E2E28 0%, #4D4C48 100%)'});

For safari :

$('.gradient').css({'background-image': '-webkit-linear-gradient(top,  #2E2E28 0%, #4D4C48 100%)'});

See here for a live example .

Seems to work cross-browser.

Edit :

I did a small plugin which can help you with the different colors :

;(function($) {
    var isSafari = /Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor);

    var methods = {
        init: function (settings) {

            settings = $.extend( {
              'colors'         : ['red', 'blue'],
              'direction'      : 'top'
            }, settings);

            return this.each(function(){
                if($.isArray(settings.colors) && settings.colors.length >= 2) {
                    $(this).css({ 
                        'background':
                        methods.gradientToString(settings.colors, settings.direction)
                    });
                } else {
                    $.error('Please pass an array');
                }

            });

        },
        gradientToString: function (colors, direction) {

            var nbColors = colors.length;

            //If no percent, we need to calculate them
            if(colors[0].percent === undefined) {

                //Passed only colors as an array we make it an object
                if(colors[0].color === undefined) {
                    var tmp = [];
                    for(i=0; i < nbColors; i++)
                        tmp.push({'color':colors[i]});

                    colors = tmp;
                }

                var p = 0,
                    percent = 100 / (nbColors - 1);

                //calculate percent
                for(i=0; i< nbColors; i++) {
                    p = i === 0 ? p : (i == nbColors-1 ? 100 : p + percent);
                    colors[i].percent = p;
                }
            }

            var to = isSafari ? '' : 'to';

            //build the string
            var gradientString = isSafari ? '-webkit-linear-gradient(' : 'linear-gradient(';

           gradientString += to +' '+ direction;

            for(i=0; i < nbColors; i++)
               gradientString += ', '+ colors[i].color + ' ' + colors[i].percent + '%';

            gradientString += ')';
            return gradientString;

        }

    };

    $.fn.gradientGenerator = function () {
        return methods.init.apply( this, arguments );
    };
})(jQuery);

Use it like this for example :

$('.gradient').gradientGenerator({
    colors : ['#2E2E28', '#4D4C48']
});

$('.change-color').on('click', function(e) {

    e.preventDefault();
    $('.gradient').gradientGenerator({
        colors : [{color:'#4D4C48',percent:0}, {color:'#282827', percent:30}, {color:'#2E2E28', percent: 100}],
        direction : 'left'
    });

});

See it working here .

The following function will take two colours as parameters and return the style string, as you've specified it, with the appropriate substrings replaced with the given colours.

You can see this in action here .

var makeGradientStyle = function(){
    var gradientString = '\
        /* Mozilla Firefox */ \
background-image: -moz-linear-gradient(top, {colour1} 0%, {colour2} 100%);\
        /* Opera */ \
        background-image: -o-linear-gradient(top, {colour1} 0%, {colour2} 100%);\
        /* Webkit (Safari/Chrome 10) */ \
        background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, {colour1}), color-stop(1, {colour2}));\
        /* Webkit (Chrome 11+) */ \
        background-image: -webkit-linear-gradient(top, {colour1} 0%, {colour2} 100%);\
        /* IE10+ */\
        background: -ms-linear-gradient(top,  {colour1} 0%,{colour2} 100%);\
        /* W3C */\
        background: linear-gradient(top,  {colour1} 0%,{colour2} 100%);\
    ';

    return function(colour1, colour2){
        return gradientString.replace(/\{colour1\}/g, colour1).replace(/\{colour2\}/g, colour2)
    }
}();

You can then apply as follows. The disadvantage lies in the fact that you're replacing the entire style string, but you can get round that with

var p = document.getElementById('p');

p.setAttribute('style', p.getAttribute('style') + '; ' + makeGradientStyle('#ff0000', '#0000ff'));

Building on Barney's excellent answer, here is a small jQuery plug-in:

(function($) { 

  $.fn.cssGradient = function(options) {

    // support multiple elements

    if(this.length > 1){
      this.each(function(){
        $(this).cssGradient(options);
      });
      return this;
    }

    // private variables

    var that = this;

    var metaData = {};
    metaData['version'] = "1.0.0";

    // settings

    // Extend our default options with those provided.
    // Note that the first argument to extend is an empty
    // object – this is to keep from overriding our "defaults" object.

    var defaultOptions = {
          background:'',
          color1:'',
          color2:''
        }

    var settings = $.extend({},defaultOptions,options);

    // private methods

    var init = function() {
      start();
      return that;
    }

    var start = function(){
      var element = jQuery(that);
      var attr = element.attr('style');
      var style = "";
      if (typeof attr !== typeof undefined && attr !== false) {
        style = element.attr('style') + makeGradientStyle(settings.background,settings.color1,settings.color2);
      }
      else{
        style = makeGradientStyle(settings.background,settings.color1,settings.color2);
      }
      element.attr('style',style);
    }

    var makeGradientStyle = function(background,color1,color2){
      var gradientString = 'background:{background};background-image:-moz-linear-gradient(top,{color1} 0%,{color2} 100%);background-image:-o-linear-gradient(top,{color1} 0%,{color2} 100%);background-image:-webkit-linear-gradient(top,{color1} 0%,{color2} 100%);background-image:-ms-linear-gradient(top,{color1} 0%,{color2} 100%);background-image:linear-gradient(to bottom,{color1} 0%,{color2} 100%);';
      return gradientString.replace(/\{background\}/g,background).replace(/\{color1\}/g,color1).replace(/\{color2\}/g,color2);
    }

    // public methods

    this.version = function() {
      console.log('cssGradient plugin version: ',metaData['version']);
    };

    return init();

  }

})(jQuery);

And to implement:

var cssGradient = jQuery('.foo').cssGradient({background:'#fff',color1:'#fff',color2:'#ff0000'});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM