【问题标题】:progress[value] style with react进度 [值] 风格与反应
【发布时间】:2018-05-04 04:20:57
【问题描述】:

我想要一个进度条,它是一个多条。看起来像这样:

[----------][----50%    ][        ]
[---20%    ][           ][        ]
[----------][-----------][---80%  ]

它具有三个不同的部分,RED-GREEN-RED:

[ RED RED  ][GREEN GREEN][ RED RED]

是实时的,值来自远程json api, 如果该值在绿色区域内,则一切正常,否则 同事需要采取的行动(如果它在所需区域之下或之上)。

到目前为止,我实现了 html+css,在 Firefox 和 Chrome 中运行良好。 这是 jsfiddle 上的演示项目:

现在我需要“反应”代码,才能活着:)

问题是,我不能内联样式以下 CSS 规则:

    progress[value]::-webkit-progress-value { /* Chrome */
  background-image:
    -webkit-linear-gradient(
      135deg,
      transparent 33%,
      rgba(0, 0, 0, 0.1) 33%,
      rgba(0, 0, 0, 0.1) 66%,
      transparent 66%
    ),
    -webkit-linear-gradient(
      top,
      rgba(255, 255, 255, 0.25),
      rgba(0, 0, 0, 0.25)
    ),
    -webkit-linear-gradient(
      left,
      rgba(255,0,0,0.8),
      rgba(255,0,0,0.8) 37.5%,
      rgba(0,255,0,0.8) 37.5%,
      rgba(0,255,0,0.8) 87.5%,
      rgba(255,0,0,0.8) 87.5%
    );
}

反应后的 Progressbar.js 相当简单:

const Progressbar = ({percent, min, max}) => {

  let styleProgress = {  backgroundImage:
    `linear-gradient(
      90deg,
      rgba(255,0,0,0.1),
      rgba(255,0,0,0.1) ${min}%,
      rgba(0,255,0,0.1) ${min}%,
      rgba(0,255,0,0.1) ${max}%,
      rgba(255,0,0,0.1) ${max}%)`
  };

  return(
      <div className="wrapper-progressbar">
        <progress style={styleProgress} max="100" value={percent}>
        </progress>
      </div>
  );
};

我可以设置微弱的背景(因此最小值和最大值始终可见),但不能设置实际的进度条。

有人知道如何使用 React 制作动态 CSS 选择器吗?

ps:只需要 Chrome 和 Firefox 支持,因为它最终会成为控制室中的电视(Kiosk 模式)。 所以根本不需要 IE 支持。 html5 &lt;progress&gt; 元素将是正确的解决方案恕我直言。

更新:这是一个演示反应项目: https://jsfiddle.net/ave0x0nb/3/

进度条要么是单色(红色 0-30%),有两种颜色(红色 0-30%,绿色 30-70%),要么是三色(红色 0-30%,绿色 30-70%,红色70-100%) 取决于实际值。 因此,如果值为 50%,则它有两种颜色(0-30% 红色和 30-50% 绿色)。

现在的问题(以及因此的问题),它总是三色的(上面的反应演示项目),并且不尊重背景进度条的限制。 请参阅 20%、50%、80% jsfiddle 演示项目以供参考。

Update2:我添加了一个动画作为参考。

【问题讨论】:

标签: javascript css reactjs


【解决方案1】:

function updateValue(){
	const progress = document.querySelector('progress');  
  progress.value = Math.round(Math.random()*100) + 1;
  console.log(progress.value);
}

const interval = setInterval(updateValue, 500);

setTimeout(function () {
	clearInterval(interval);
}, 4000);
.wrapper-progressbar {
  flex: 1;
}

progress {
  width: 100%;
  background-image:
    linear-gradient(
      90deg,
      rgba(255,0,0,0.1),
      rgba(255,0,0,0.1) 30%,
      rgba(0,255,0,0.1) 30%,
      rgba(0,255,0,0.1) 70%, 
      rgba(255,0,0,0.1) 70%);
  border: 0;
  height: 2em;
  border-radius: 9px;
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.25) inset;
}

progress[value]::-webkit-progress-bar {
  width: 100%;
  background: transparent;
  background-image:
    -webkit-linear-gradient(
      left,
      rgba(255,0,0,0.1),
      rgba(255,0,0,0.1) 30%,
      rgba(0,255,0,0.1) 30%,
      rgba(0,255,0,0.1) 70%,
      rgba(255,0,0,0.1) 70%);
  border: 0;
  height: 2em;
  border-radius: 9px;
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.25) inset;
}

progress[value] {
  background-color: transparent;
  border-radius: 5px;
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.25) inset;
  position: relative;
  /* Reset the default appearance */
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  /* Get rid of default border in Firefox. */
  /*border: none;*/
}

progress[value]::-moz-progress-bar { /* Firefox */
  border-radius: 2px;
  background-size: 65px, 100%, 100%;
  background-color: transparent;
  background-image:
    -moz-linear-gradient(
      135deg,
      transparent 33%,
      rgba(0, 0, 0, 0.1) 33%,
      rgba(0, 0, 0, 0.1) 66%,
      transparent 66%
    ),
    -moz-linear-gradient(
      top,
      rgba(255, 255, 255, 0.25),
      rgba(0, 0, 0, 0.25)
    ),
    -moz-linear-gradient(
      left,
      rgba(255,0,0,0.8),
      rgba(255,0,0,0.8) 100%,
      rgba(0,255,0,0.8) 100%,
      rgba(0,255,0,0.8) 100%,
      rgba(255,0,0,0.8) 100%
    );
}

progress[value]::-webkit-progress-value { /* Chrome */
  border-radius: 2px;
  background-size: 65px, 100%, 100%;
  background-color: transparent;
  background-image:
    -webkit-linear-gradient(
      135deg,
      transparent 33%,
      rgba(0, 0, 0, 0.1) 33%,
      rgba(0, 0, 0, 0.1) 66%,
      transparent 66%
    ),
    -webkit-linear-gradient(
      top,
      rgba(255, 255, 255, 0.25),
      rgba(0, 0, 0, 0.25)
    ),
    -webkit-linear-gradient(
      left,
      rgba(255,0,0,0.8),
      rgba(255,0,0,0.8) 100%,
      rgba(0,255,0,0.8) 100%,
      rgba(0,255,0,0.8) 100%,
      rgba(255,0,0,0.8) 100%
    );
}
    <div className="wrapper-progressbar">
      <progress style={styleProgress} max="100" value="90"></progress>
    </div>

【讨论】:

  • 你错过了重点。进度条是三色的。你的全是红色的。以 80% 为例:jsfiddle.net/4cLa8kra
【解决方案2】:

使用classnames npm 包。您可以在组件中发送进度(例如 20%、50%、80%),并相应地将组件中的类名应用为:

progressBarClass = classNames('defaultClass', {
        'green': props.progress < PROGRESS_VALUE.green,
        'yellow': PROGRESS_VALUE.green < props.progress < PROGRESS_VALUE.yellow,
        'red': props.progress > PROGRESS_VALUE.red
      }),

在渲染中:

render(){
   return (
       <div classNames={progressBarClass}>{'progress-bar'}</div>   
   );
}

在css文件中:

.green {
  //...green styles
}

.yellow {
  //...yellow styles
}


.red {
  //...red styles
}

我还没有编写确切的代码,但是您可以有条件地应用这样的类。而不是使用 inline-css,因为它会使您的代码不可读,而且我个人不喜欢 inline-styles。

【讨论】:

  • 您的进度条是绿色或黄色或红色。虽然我想要一个具有三种颜色(高于 70%)、两种颜色(高于 30%)和低于 30% 的单色的进度条。今晚我将制作一个动画 gif,以使其更加清晰。这个“显示器”将用一系列 LED 代替旧的物理显示器,看起来像这样:[G][G][G][R][R][R][G][G][G],所以这个进度条必须模仿一系列 LED。
  • 我没有给你确切的解决方案,而是一个要点,它应该如何完成而不是给它添加内联样式。我想你可以自己编写解决方案,如果你知道怎么做,作为 stackoverflow 社区,这就足够了
  • 按照你的想法,我应该创建 100 条 CSS 规则,并按百分比应用它们。这是一种蛮力,不是吗?否则你可能会误解问题。
  • 暴力破解?将有 3 种样式,它们将被隔离且更易于理解。而不是弄乱你的整个 CSS 文件,你可以只创建 3 个类(或更多),去掉一些常见的样式,你就可以编写可维护的代码。
  • 我上传了一个动画(原帖)。我无法想象如何使用您的 css 类复制该动画,除非我为每个百分比值创建一个类:class_000、class_001 ... class_099、class_100。我的解决方案是否遗漏了什么?
猜你喜欢
  • 2019-07-05
  • 2018-07-09
  • 2013-05-25
  • 2011-02-08
  • 1970-01-01
  • 1970-01-01
  • 2011-08-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多