一个在 React 中 css 实现进度条的思路,然后随之而来的由 linear-gradient alpha 导致的一个坑

善良单纯的小阿板
创建时间: 2019年8月9日 庆丰七年
最后编辑: 2019年8月9日 5 年前
一切开始自产品小姐姐更改的一个需求:要在下载按钮上,增加进度显示

之前做这种需求,都是去 google 然后嫖一个就行了。这次招嫖的过程中,前几篇文章都是用 border 或是子元素撑开,这也忒乔碧萝了——原来的代码结构是很简单的,子元素也忒不优雅了。

原按钮结构

<a href="javascript:void(0);" 
  className={btnClass}
  statecode={ginfo.statecode||'11'} 
  statetype={ginfo.statetype||'install'}>
  {ginfo.statetext}
</a>

并不愿意在里边再加上一层套套,然后又想起了前几天看过的 css trick (吃屎屎技巧,就想用linear-gradient来实现。

众所周知,linear-gradient在人人人都知道的渐变玩法之外,还可以按角度和切分点进行渐变处理,例见 MDN 的 demo。所以我们只需要根据进度百分比来对 "gradient" 进行一次"陡峭的"切分,把 "gradient" 变成 "cliff" 就好了。

background: linear-gradient(to right, #233 40%, #999 40%);

这样就可以简单地在从左至右方向,40%的地方截断

[图片1 待上传哦]

在 React 中,我就很拙略地写了个方法来控制style

genetateLoadingBar(ginfo){
  if(ginfo.statecode != mConst.GAME_STATS_CONFIG.DOWNING.c){
      return null
  }
  const percent = ginfo.statetext
  return {
      background: `linear-gradient(to right, #19cf86 ${percent} , #fff ${percent})`,
  }
}

render(){
  return (
    <a href="javascript:void(0);"
      className={btnClass}
      statecode={ginfo.statecode || '11'}
      statetype={ginfo.statetype || 'install'}
      style={this.genetateLoadingBar(ginfo)}>
      {ginfo.statetext}
    </a>
  )
}

按理来说,本来事情已经可以结束了,但是我又想,为什么要写死未到达部分的颜色呢,改成透明不是更优雅?

background: `linear-gradient(to right, #19cf86 ${percent} , #fff0 ${percent})`,

这个想法真的是太ok了,chrome 里测了一下也是美滋滋,高高兴兴 build 一下,放到了测试环境,但是在安卓客户端下,却不能显示渐变。

第一反应当然是 x5 背锅了,那么魔改的东西(被打。但是另外运行了 MDN 的那个 demo,在 x5 上展示正常。

心生疑问,这都9102年了,caniuse 和 MDN 兼容表我也查了,没问题啊。然后开始了一波测试

|环境|结果 |--- |Android Chrome v75|正常 |miui 自带浏览器 v10.4.8|异常 |Via with webview v76.0.3809.89|异常 |x5 Tbs debug v魔改|异常

查询无果之后,在手敲属性的时候,发现

background: linear-gradient(to right, #233 40%, #9990 40%);

在输入 #9990 后会报 invalid。

所以定位到问题,Android webview 无法在 linear-gradient中使用透明色...,推测可能与硬件加速有关