- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在做 FCC 练习 Pomodoro Clock 这样的作品。我认为问题是当倒计时到了最后一分钟时,pause 将不起作用。顺便说一句,如果不是最后一分钟,暂停 会起作用。我怀疑这个问题导致其他测试失败。还测试说 reset 功能不起作用,但它有效。
编辑:更深入地解释我的问题:方法 paused() 用于将状态 paused 从 false 更改为 true ,反之亦然。该方法在 timer() 方法内部调用,该方法的工作也是启动 setInterval。 setInterval 设置在变量this.clearTimer 中。如果它是 paused true 则启动 clearInterval() 并停止计时器。
当带有 start_stop id 的元素被点击时,paused 发生变化,评估发生,正如我之前所说的那样; false => setInterval 去; true => setInterval 停止。
未暂停时,根据状态中记录的值设置间隔。问题是,当您暂停低于一分钟(59、58 等秒)的计时器时,尽管暂停的状态从真变为假,它也不会恢复倒计时?!如果倒计时超过 1 分钟,则开始/暂停按规定工作。
您可以在以下位置查看代码:my pen
这是主要组件的代码(来自本地源):
import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.css';
import './style.scss';
import Item from "./item.js";
import Arrow from "./arrow.js";
import Fa from "./fa.js";
class Pomodoro extends React.Component {
constructor(props) {
super(props);
this.state = {
breakLength: 5,
multiplier: 25,
base: 1000,
time: 0,
minutes: 25,
seconds: 60,
paused: false,
session: false,
break: true,
disabled: false,
};
this.increment = this.increment.bind(this);
this.decrement = this.decrement.bind(this);
this.timer = this.timer.bind(this);
this.reset = this.reset.bind(this);
this.paused = this.paused.bind(this);
this.myRef = React.createRef();
this.clearTimer = null;
}
componentDidMount(){
this.setState({
time: ""+(this.state.multiplier*this.state.base*60),
minutes: this.state.multiplier,
seconds: this.state.seconds === 60 ? "00" : this.state.seconds ,
});
}
paused(){
this.setState({
paused: !this.state.paused
});
}
timer(){
this.paused();
if(this.state.paused === false){
if((this.state.minutes!==0 && this.state.seconds!==0) || (this.state.seconds!==0)){
this.clearTimer = setInterval(() => {
if(this.state.session===false){
console.log("Sada ide session.");
this.setState({
time: ""+(this.state.time-this.state.base),
minutes: this.state.minutes > 0 ? Math.floor(((this.state.time-this.state.base)/(this.state.base))/60) : this.state.minutes,
seconds: this.state.seconds > 0 ? this.state.seconds-1 : 59,
session: (this.state.minutes===0 && this.state.seconds===1) ? true : false,
break: (this.state.minutes===0 && this.state.seconds===1) ? false : true,
});
}
if(this.state.break===false && this.state.session===true && this.state.time==="0"){
console.log("Kraj session-a. Sada ide resetovanje, pa break.");
this.setState({
time: ""+(this.state.breakLength*this.state.base*60),
minutes: this.state.breakLength,
seconds: 60,
});
}
if(this.state.break===false){
console.log("Sada ide break.");
this.setState({
time: ""+(this.state.time-this.state.base),
minutes: this.state.minutes > 0 ? Math.floor(((this.state.time-this.state.base)/(this.state.base))/60) : this.state.minutes,
seconds: this.state.seconds > 0 ? this.state.seconds-1 : 59,
session: (this.state.minutes===0 && this.state.seconds===1) ? false : true,
break: (this.state.minutes===0 && this.state.seconds===1) ? true : false,
});
}
if(this.state.break===true && this.state.session===false && this.state.time==="0"){
console.log("Kraj break-a. Sada ide resetovanje, pa session.");
this.setState({
time: ""+(this.state.multiplier*this.state.base*60),
minutes: this.state.multiplier,
seconds: this.state.seconds === 60 ? "00" : this.state.seconds,
});
}
}, this.state.base);
}
}
else{
clearInterval(this.clearTimer);
}
}
reset(){
this.myRef.current.pause();
this.myRef.current.currentTime = 0;
clearInterval(this.clearTimer);
this.clearTimer = null;
this.setState({
breakLength: 5,
multiplier: 25,
base: 1000,
time: ""+(25*1000*60),
minutes: 25,
seconds: 60,
paused: false,
session: false,
break: true,
disabled: false,
});
}
increment(e){
console.log(e.target.id);
let myId = e.target.id;
if(myId==="break-increment"){
this.setState({
breakLength: this.state.breakLength <60 ? this.state.breakLength+1 : this.state.breakLength,
});
}
else if(myId==="session-increment"){
this.setState({
multiplier: this.state.multiplier < 60 ? this.state.multiplier+1 : this.state.multiplier,
time: this.state.time !== "60" ? ""+((this.state.multiplier+1)*this.state.base*60) : this.state.time,
minutes: this.state.minutes < 60 ? this.state.multiplier+1 : this.state.minutes,
});
}
}
decrement(e){
console.log(e.target.id);
let myId = e.target.id;
if(myId==="break-decrement" && this.state.breakLength > 1){
this.setState({
breakLength: this.state.breakLength > 1 ? this.state.breakLength-1 : this.state.breakLength,
});
}
else if(myId==="session-decrement" && this.state.multiplier > 1 && this.state.time > 1 && this.state.minutes > 1){
this.setState({
multiplier: this.state.multiplier > 1 ? this.state.multiplier-1 : this.state.multiplier,
time: this.state.time > 1 ? (""+((this.state.multiplier-1)*this.state.base*60)) : this.state.time,
minutes: this.state.minutes > 1 ? this.state.multiplier-1: this.state.minutes,
});
}
}
render(){
//console.log(this.state);
const minutes = (""+this.state.minutes).length===1 ? "0"+this.state.minutes : this.state.minutes;
const seconds = this.state.seconds===60 ? "00" : ((""+this.state.seconds).length===1 ? "0"+this.state.seconds : this.state.seconds);
const time = minutes+":"+seconds;
if(time==="00:00"){
console.log("1: "+time);
console.log("2: "+this.state.minutes+":"+this.state.seconds);
this.myRef.current.play();
}
/*if((this.state.minutes+":"+this.state.seconds)===time){
alert("alert2: "+this.state.minutes+":"+this.state.seconds);
}*/
const lastSesMin = (minutes==="00") ? {color: 'red',} : {};
const decrement = this.clearTimer ? ()=>{} : this.decrement;
const increment = this.clearTimer ? ()=>{} : this.increment;
const item2Head = <h3 id="break-label">Break Length</h3>;
const fa1 = <Fa klasa={"fa fa-arrow-down fa-2x"} id={"break-decrement"} onClick={decrement}/>;
const fa2 = <Fa klasa={"fa fa-arrow-up fa-2x"} id={"break-increment"} onClick={increment}/>;
const arr1 = [<Arrow klasa={"arrow"} key={0} arrow={item2Head}/>, <br key={1}/>, <Arrow klasa={"arrow"} key={2} arrow={fa1}/>, <Arrow id={"break-length"} klasa={"nums"} key={3} arrow={this.state.breakLength}/> , <Arrow key={4} klasa={"arrow"} arrow={fa2}/>];
const item3Head = <h3 id="session-label">Session Length</h3>;
const fa3 = <Fa klasa={"fa fa-arrow-down fa-2x"} id={"session-decrement"} onClick={decrement}/>;
const fa4 = <Fa klasa={"fa fa-arrow-up fa-2x"} id={"session-increment"} onClick={increment}/>;
const arr2 = [<Arrow klasa={"arrow"} key={0} arrow={item3Head}/>, <br key={1}/>, <Arrow klasa={"arrow"} key={2} arrow={fa3}/>, <Arrow klasa={"nums"} id={"session-length"} key={3} arrow={this.state.multiplier}/> , <Arrow key={4} klasa={"arrow"} arrow={fa4}/>];
const countdownLabel = (this.state.session===false && this.state.break===true) ? "Session" : "Break";
const item4Head = <h3 key={0} id={"timer-label"} style={lastSesMin}>{countdownLabel}</h3>;
const nums2 = <div key={1} className="nums" style={lastSesMin} id={"time-left"}>{time}</div>;
const arr3 = [item4Head, nums2];
const fa5 = <Fa key={0} klasa={"fa fa-play arrow controls"} title={"start-pause"}/>;
const fa6 = <Fa key={1} klasa={"fa fa-pause arrow controls"} title={"start-pause"}/>;
const fa7 = <Fa key={2} klasa={"fa fa-refresh arrow controls"} id="reset" title={"reset"} onClick={this.reset}/>;
const startPause = <div id="start_stop" key={4} onClick={this.timer}>{fa5}{fa6}</div>;
const arr4 = [startPause, fa7];
return(
<div className="grid-container cent">
<Item klasa={"item1"} arrowsAndNums={"Pomodoro Clock"}/>
<Item klasa={"item2"} arrowsAndNums={arr1}/>
<Item klasa={"item3"} arrowsAndNums={arr2}/>
<Item klasa={"item4"} arrowsAndNums={arr3}/>
<Item klasa={"item4"} arrowsAndNums={arr4}/>
<audio ref={this.myRef} id="beep" src="http://soundbible.com/grab.php?id=2158&type=wav"></audio>
</div>
);
}
}
ReactDOM.render(<Pomodoro/>, document.getElementById('root'));
编辑2:我解决了暂停问题。我刚刚将 if(this.state.minutes!==0 && this.state.seconds!==0){
行更改为 if((this.state.minutes!== 0 && this.state.seconds!==0) || (this.state.seconds!==0)){
.
这里有一些图像显示了测试错误,即使应该没有错误。PS:对于练习的错误测试,它使用了 fcc 的错误测试脚本,这就是产生这些假定错误的原因。
编辑4:正如我最近发现的那样,即使是 FCC 的番茄钟有时也会失败。有时在不同的浏览器中,有时在星期天,有时等等......长话短说,我设计了新代码,解决了我之前所做编辑中的问题。尽管如此,它仍然存在与上述 fcc 的番茄钟相同的问题。我在某处读到一些关于计时事件的内容,其实现和执行取决于浏览器,在这种情况下,测试套件本身使用,我的番茄钟也是如此。所以应该有各种各样的“冲突”......解决这些不一致和冲突,以便在每个浏览器中,在每一个诉讼/测试中,看起来都无法克服,我想会......我想问的是,可以吗如果我提交我的番茄钟,关于所说的一切?我的改进pomodoro添加了解释代码功能的注释,请随意浏览。我的测试失败的图像:在左上角,您可以看到 28/29 通过的测试。注意:您可以在 codepen 中看到更新后的代码以及注释。
最佳答案
只是阅读了一些代码(没有测试你的沙箱),但我发现了一个问题,由于可能的竞争条件,可能会导致一些模糊的错误:
paused(){
this.setState({
paused: !this.state.paused
});
}
timer(){
this.paused();
if(this.state.paused === false){
// ...
timer()
正在调用 paused
,其中状态已更新。然后 timer()
检查新状态。
问题:
setState
may be batched ,因此对 paused
的连续调用可能基于某个值。解决方案:使用函数作为状态更新器:
setState(prevState => ({
paused: !prevState.paused
}));
setState
may be asynchronous (相同的链接),因此 paused
状态在 timer()
中读取时可能不会反射(reflect)该更改!解决方案:使用回调作为 setState()
的第二个参数:
setState(prevState => ({
paused: !prevState.paused
}), () => {
// You can read updated this.state.paused here....
});
所以整个代码片段可以这样实现:
paused(callback){
setState(prevState => ({
paused: !prevState.paused
}), callback);
}
timer(){
this.paused(() => {
// if(this.state.paused === false){
// ...
});
但是如果你有很多这样的地方,你很快就会陷入某种回调 hell 。并且在这些状态变化的同时管理停止/启动计时器本身可能会变得非常棘手。你至少可以简化你的计时器,但让它始终运行(从 componentDidMount()
开始,在 componentWillUnmount()
停止)并决定每个滴答做什么(例如做“暂停”或让“暂停”指示灯闪烁时什么都没有...)
旁注:像 base
这样的变量不需要处于状态,因为它们只是不需要触发组件重新渲染的内部变量。
关于javascript - FCC 番茄时钟未通过内置测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57798187/
我找到了 this excellent question and answer它以 x/y(加上 center x/y 和 degrees/radians)开始并计算旋转- 到 x'/y'。这个计算很
全部: 我已经创建了一个 Windows 窗体和一个按钮。在另一个线程中,我试图更改按钮的文本,但它崩溃了;但是如果我尝试更改按钮的颜色,它肯定会成功。我认为如果您更改任何 Windows 窗体控件属
本网站的另一个问题已证实,C 中没有缩写的字面后缀,并且可以执行以下操作: short Number = (short)1; 但是转换它和不这样做有什么区别: short Number = 1; 您使
我有下表: ID (int) EMAIL (varchar(50)) CAMPAIGNID (int) isSubscribe (bit) isActionByUser (bit) 此表存储了用户对事
也就是说,无需触发Javascript事件即可改变的属性,如何保留我手动选中或取消选中的复选框的状态,然后复制到另一个地方? 运行下面的代码片段并选中或取消选中其中的一些,然后点击“复制”: $('#
我在网上找到的所有关于递增指针导致段错误的示例都涉及指针的取消引用 - 如果我只想递增它(例如在 for 循环的末尾)并且我不在乎它是否最终进入无效内存,因为我不会再使用它。例如,在这个程序中,每次迭
我有一个 Spring MVC REST 服务,它使用 XStream 将消息与 XML 相互转换。 有什么方法可以将请求和响应中的 xml(即正文)打印到普通的 log4j 记录器? 在 Contr
做我的任务有一个很大的挑战,那就是做相互依赖的任务我在这张照片中说的。假设我们有两个任务 A 和 B,执行子任务 A1、A2 和 B1、B2,假设任务 B 依赖于 A。 要理想地执行任务 B,您应该执
通过阅读该网站上的几个答案,我了解到 CoInitialize(Ex) should be called by the creator of a thread 。然后,在该线程中运行的任何代码都可以使
这个问题已经困扰我一段时间了。我以前从未真正使用过 ListViews,也没有使用过 FirebaseListAdapters。我想做的就是通过显示 id 和用户位置来启动列表的基础,但由于某种原因,
我很难解释这两个(看似简单)句子的含义: “受检异常由编译器在编译时检查” 这是什么意思?编译器检查是否捕获了所有已检查的异常(在代码中抛出)? “未经检查的异常在运行时检查,而不是编译时” 这句话中
我有一个包含排除子字符串的文本文件,我想迭代该文件以检查并返回不带排除子字符串的输入项。 这里我使用 python 2.4,因此下面的代码可以实现此目的,因为 with open 和 any 不起作用
Spring 的缓存框架能否了解请求上下文的身份验证状态,或者更容易推出自己的缓存解决方案? 最佳答案 尽管我发现这个用例 super 奇怪,但您可以为几乎任何与 SpEL 配合使用的内容设置缓存条件
我有以下函数模板: template HeldAs* duplicate(MostDerived *original, HeldAs *held) { // error checking omi
如果我的应用程序具有设备管理员/设备所有者权限(未获得 root 权限),我如何才能从我的应用程序中终止(或阻止启动)另一个应用程序? 最佳答案 设备所有者可以阻止应用程序: DevicePolicy
非常简单的问题,但我似乎无法让它正常工作。 我有一个组件,其中有一些 XSLT(用于导航)。它通过 XSLT TBB 使用 XSLT Mediator 发布。 发布后
我正在将一个对象拖动到一个可拖放的对象内,该对象也是可拖动的。放置对象后,它会嵌套在可放置对象内。同样,如果我将对象拖到可放置的外部,它就不再嵌套。 但是,如果我经常拖入和拖出可放置对象,则可拖动对象
我正在尝试为按钮和弹出窗口等多个指令实现“取消选择”功能。也就是说,我希望当用户单击不属于指令模板一部分的元素时触发我的函数。目前,我正在使用以下 JQuery 代码: $('body').click
我从 this question 得到了下面的代码,该脚本用于在 Google tasks 上更改 iframe[src="about:blank"] 内的 CSS使用 Chrome 扩展 Tempe
我有一些 @Mock 对象,但没有指定在该对象上调用方法的返回值。该方法返回 int (不是 Integer)。我很惊讶地发现 Mockito 没有抛出 NPE 并返回 0。这是预期的行为吗? 例如:
我是一名优秀的程序员,十分优秀!