位置:海鸟网 > IT > JavaScript >

javascript线性渐变2

我们逐一分析了各浏览器的可行方法,这部分将搞鼓出一个统一的类来实现跨浏览器的线性渐变。

先来IE的,这是最大的用户群,如果这部分开发不出来,基本可以说不用做了。IE虽然有Gradient滤镜,但对比其他浏览器的实现特弱,没有多重渐变(stop-color),不能实现角度渐变,而且还经常失效。我的思路是这样,假如有一个带文本的DIV,要实现多重线性渐变,我们首先得把它里面的文本取出来,然后里面放几个DIV,有几重就放几个,然后把它们渐变。如果是垂直渐变,这好办,什么也不用做,只需设置其滤镜与各个高就行了。如果水平,就让其浮动或绝对定位,放到适当的位置,设置其滤镜与宽。但渐变滤镜竟然会在浮动后或定位后失效,这是在使用透明滤镜时闻所未闻的。没有办法,祭出上古神器table。但设置长与宽时,使用style来设置是不顶用的,一定要用DOM属性。渐变则由它的td元素负责。为了去除table元素与td元素之间,td元素与其内容之间的空白,我们还得用到cellPadding与cellSpacing。

01.//④使用IE滤镜实现渐变

02.function setFilter(el,start,end,type){

03.  el.style.filter = "progid:DXImageTransform.Microsoft.Gradient(enabled='true',startColorstr="+start+",GradientType="+type+", endColorstr="+end+")";

04.}

05.//③每个渐变体的实现,是用table还是div

06.function createStop(parent,top,left,width,height,type){

07.  if(type){

08.    var table = document.createElement("table");

09.    parent.appendChild(table);

10.    var tr = table.insertRow(0),

11.    td = tr.insertCell(0)

12.    table.height = height+"px";

13.    table.width = width+"px";

14.    table.cellPadding = 0;

15.    table.cellSpacing = 0;

16.    table.style.cssText = "position:absolute;top:"+top+"px;left:"+left+"px"

17.    td.innerHTML =" ";

18.    return td;

19.  }

20.  var div = document.createElement("div");

21.  parent.appendChild(div);

22.  div.style.height = height+"px";

23.  div.style.width = width+"px";

24.  return div;

25.}

26.//②渐变的具体实现,确定要使用多少渐变体,每个渐变体的颜色(是渐变色还是纯色)与长宽坐标

27.var IEgradient = function(entity,stops,width,height,type){

28.  var offset,color,beforeColor,stopWidth,stopHeight,left,top,stop;

29.  for(var i=0,j=0,l=stops.length;i<l;i++,j++){

30.    offset = stops[i].split(",")[0];

31.    color =  stops[i].split(",")[1];

32.    stopWidth = (offset/100 * width).toFixed(1);

33.    stopHeight = (offset/100 * height).toFixed(1);

34.    switch(i){

35.      case 0 :

36.        beforeColor = color;

37.        left = stopWidth;

38.        top = stopHeight;

39.        if(offset != 0){

40.          //插入一个纯色的table

41.          stop = type?  createStop(entity,0,0,stopWidth,height,type) :

42.            createStop(entity,0,0,width,stopHeight,type);

43.          stop.style.backgroundColor = color;

44.        }

45.        break;

46.      case l-1:

47.        //先插入一个渐变的table

48.        var w2 = ((100-offset)/100 * width).toFixed(1),

49.        h2 = ((100-offset)/100 * height).toFixed(1),

50.        stop =  type? createStop(entity,0,left,width - left -w2,height,type):

51.          createStop(entity,0,0,width,height - top -h2,type);

52.        setFilter(stop,beforeColor,color,type);

53.        if(offset != 100){

54.          //再插入一个纯色的table

55.          var stop2 = type? createStop(entity,0,stopWidth,w2,height,type):

56.            createStop(entity,0,0,width,h2,type);

57.          stop2.style.backgroundColor = color;

58.        }

59.        break;

60.      default :

61.        //插入一个渐变的table

62.        stop = type ? createStop(entity,0,left,stopWidth - left,height,type) :

63.          createStop(entity,0,0,width,stopHeight-top,type);

64.        setFilter(stop,beforeColor,color,type);

65.        beforeColor = color;

66.        left = stopWidth;

67.        top = stopHeight;

68.        break;

69.    }

70.  }

71.}

72.//①渐变的主体函数

73.var gradient = function(id){

74.  var entity = document.getElementById(id),

75.  options = arguments[1] || {},

76.  width = options.width,

77.  height = options.height,

78.  type = options.type ,

79.  stops = options["color-stop"];

80.  entity.style.position = "relative";

81.  var content = entity.innerHTML;

82.  entity.innerHTML = "";

83.  //向目标对象进行渐变。

84.  IEgradient(entity,stops,width,height,type);

85.  //把原来的内容重新加入的目标对象。

86.  var contentDiv = document.createElement("div");

87.  contentDiv.style.cssText =  "position:absolute;top:0;left:0";

88.  contentDiv.innerHTML = content;

89.  entity.appendChild(contentDiv);

90.}

运行代码

safari,chrome与opera打算都用SVG实现。为了减少函数的长度,特意搞了两个辅助函数。

01.var createSVG = function(tag){

02.  return document.createElementNS("",tag);

03.};

04.var attr= function(node,bag){

05.  for(var i in bag){

06.    if(bag.hasOwnProperty(i))

07.      node.setAttribute(i,bag[i])

08.  }

09.};

10.var COSgradient = function(entity,stops,width,height,type){

11.  var svg = createSVG("svg");

12.  attr(svg,{width:width+"px",height:height+"px"})

13.  entity.appendChild(svg);

14.  var defs = createSVG("defs");

15.  svg.appendChild(defs);

16.  var linearGradient = createSVG("linearGradient");

17.  defs.appendChild(linearGradient);

18.  attr(linearGradient,{id:"nasami",x1:"0%",y1:"0%"})

19.  if(type){

20.    attr(linearGradient,{x2:"100%",y2:"0%"})

21.  }else{

22.    attr(linearGradient,{x2:"0%",y2:"100%"})

23.  }

24.  for(var i=0,j=0,l=stops.length;i<l;i++,j++){

25.    var offset = stops[i].split(",")[0] + "%",

26.    color =  stops[i].split(",")[1],

27.    stop = createSVG("stop");

28.    attr(stop,{offset:offset,"stop-color":color});

29.    linearGradient.appendChild(stop);

30.  }

31.  var rect = createSVG("rect");

32.  svg.appendChild(rect);

33.  attr(rect,{x:"0px",y:"0px",width:width+"px",height:height+"px",fill:"url(#nasami)"});

34.}

firefox则利用其私有属性:

01.var FFgradient= function(entity,stops,width,height,type){

02.  var cssText = ";background: -moz-linear-gradient("

03.  cssText += type?  "top,bottom," :"left,right,";

04.  for(var i=0,j=0,l=stops.length;i<l;i++,j++){

05.    var offset = stops[i].split(",")[0] + "%",

06.    color =  stops[i].split(",")[1];

07.    cssText += "color-stop("+[offset,color]+"),"

08.  }

09.  cssText = cssText.replace(/,$/,"")+") no-repeat;";

10.  entity.style.cssText = cssText+"width:"+width+"px;height:"+height+"px;"

11.}

不过今天研磨一下,发现firefox还是支持SVG的线性渐变的,因此纠正我原来的观点。上面的函数只是作用一种实现手段放在这里,它并没有整合到我最终的版本中(虽然它比SVG实现短很多。)这样一来,在老一点版本的firefox中我们也能实现线性渐变了。

下面这个运行框里的渐变效果可在所有主流浏览器中正常运作。

运行代码

再把它做成类。扼要说明一下:它的第一个参数为IE,第二个为哈希。哈希中的各参数都为必选的,width,height的单位为px;type为0或者1,0代表垂直,1为水平;color-stop代表渐变体,由一个字符串数组构成,每个字符串都是由数字加逗号加颜色值组成,数字表代偏移量,单位为%,颜色值可以是red,green等名词,也可以是六位或三位的哈希值。渐变体至少要有一个。

1.   

2.new Gradient("gradient",{width:800,height:100,type:0,"color-stop":["0,red",

3."16,orange","32,yellow","48,green","64,blue","80,indigo","100,violet"]})

运行代码