2017-06-20 3 views
5

期待やり方に従事していません:`setTimeout`は私がドラッグしたときに変更した数値で範囲の入力フィールドを持っている

enter image description here

私は右にすべての方法をドラッグすると、入力の最大値が増加します。

enter image description here

私はすべて左への道、最小値をドラッグすると:私は(onMouseUpのかonTouchEnd)を解放するとき、私はさらにドラッグ&ドラッグすることで最大の増加続けることができるように続いて、最大値が減少しますが減少する。私は(onMouseUpの又はonTouchEnd)を放出するときに、私はさらにドラッグアンドドラッグすることにより分を減少させる続けることができるように、最小値が増加し:

enter image description here

私はいつも、たとえば99の範囲を有していなければなりません

Iは、2つの再帰setTimeoutが変化minmax値の集合sを有する:私は分値が431

問題となる、530に最大値が増加しています。

ユーザーが最初にいずれかの側にドラッグすると、番号がゆっくりと変更されます。 2秒間押し続けると、その数はより早く増加するはずです。関連コード:

// After arbitrary period, increase the rate at which the max value increments 
this.fasterChangeStake = setTimeout(() => { 
    this.stakeChangeTimeout = this.FAST_STAKE_CHANGE_TIMEOUT; 
}, 2000); 

これは初めての動作です。

enter image description here

これは、タイムアウトの私の清算にもかかわらず、ドラッグが終了されています:

clearTimeout(this.increaseStakeLimits); 
clearTimeout(this.decreaseStakeLimits); 
clearTimeout(this.timer); 

はなぜ魅力ではない最初の(遅い)タイムアウトですが、その後の回は、それが最初に速く、タイムアウトにラッチ?

Codepen:https://codepen.io/alanbuchanan/pen/NgjKMa?editors=0010

JS:

const {observable, action} = mobx 
const {observer} = mobxReact 
const {Component} = React 

@observer 
class InputRange extends Component { 
    constructor() { 
    super(); 
    this.INITIAL_STAKE_CHANGE_TIMEOUT = 200; 
    this.FAST_STAKE_CHANGE_TIMEOUT = 20; 
    this.SNAP_PERCENT = 10; 
    this.increaseStakeLimits = this.increaseStakeLimits.bind(this); 
    this.decreaseStakeLimits = this.decreaseStakeLimits.bind(this); 
    } 

    @observable min = 0; 
    @observable max = 99; 
    @observable stakeChangeTimeout = this.INITIAL_STAKE_CHANGE_TIMEOUT; 
    @observable isIncreasing = false; 
    @observable isDecreasing = false; 
    @observable stake = 0; 
    @action updateStake = (amount) => { 
    if (amount > -1) { 
     this.stake = amount 
    } 
    }; 

    increaseStakeLimits() { 
    const { updateStake } = this; 

    this.max = this.max += 1; 
    this.min = this.max - 99 
    updateStake(this.max); 

    // After arbitrary period, increase the rate at which the max value increments 
    this.fasterChangeStake = setTimeout(() => { 
     this.stakeChangeTimeout = this.FAST_STAKE_CHANGE_TIMEOUT; 
    }, 2000); 

    // Recursive call, like setInterval 
    this.timer = setTimeout(this.increaseStakeLimits, this.stakeChangeTimeout); 
    this.isIncreasing = true; 
    } 

    decreaseStakeLimits() { 
    console.warn('this.stake:', this.stake) 
    const { stake } = this 
    const { updateStake } = this; 

    this.min = this.min -= 1; 
    this.max = this.min + 99 
    updateStake(this.min); 

    // After arbitrary period, increase the rate at which the max value increments 
    this.fasterChangeStake = setTimeout(() => { 
     this.stakeChangeTimeout = this.FAST_STAKE_CHANGE_TIMEOUT; 
    }, 2000); 

    // Recursive call, like setInterval 
    this.timer = setTimeout(this.decreaseStakeLimits, this.stakeChangeTimeout); 
    this.isDecreasing = true; 

    } 

    handleStakeChange = e => { 
    clearTimeout(this.increaseStakeLimits); 
    clearTimeout(this.decreaseStakeLimits); 
    clearTimeout(this.timer); 

    const { updateStake } = this; 
    const { stake } = this; 

    const val = Number(e.target.value) 

    // User has scrolled all the way to the right 
    if (val >= this.max) { 
     console.warn("scrolled to right") 
     this.increaseStakeLimits(); 

    // User has scrolled all the way to the left 
    } else if (val <= this.min) { 
     console.warn("scrolled to left") 
     if (val > -1) { 
     this.decreaseStakeLimits(); 
     } 
    } else { 
     updateStake(val); 
    } 
    }; 

    handleRelease =() => { 
    console.warn("RANGE:", this.max - this.min) 
    console.warn("released"); 
    clearTimeout(this.fasterChangeStake); 
    clearTimeout(this.timer); 
    // Reset the timeout value to the initial one 
    this.stakeChangeTimeout = this.INITIAL_STAKE_CHANGE_TIMEOUT; 
    this.SNAP_PERCENT = 10 
    const snapAmount = this.SNAP_PERCENT 
    if (this.isIncreasing) { 
     this.max += snapAmount 
    } 

    if(this.isDecreasing && this.min > 0) { 
     this.min -= snapAmount 
    } 

    this.isIncreasing = false; 
    this.isDecreasing = false; 
    }; 

    render() { 
    const { stake } = this; 

    const style = { 
     backgroundSize: 
     (stake - this.min) * 100/(this.max - this.min) + "% 100%" 
    }; 

    return (
     <div className="rangeContainer"> 
     <div>{this.stake}</div> 
     <div className="inputContainer"> 
      <input 
      id="betRangeId" 
      type="range" 
      min={this.min} 
      max={this.max} 
      step="1" 
      ref={input => { 
       this.textInput = input; 
      }} 
      value={this.stake} 
      onChange={this.handleStakeChange} 
      onTouchEnd={this.handleRelease} 
      onMouseUp={this.handleRelease} 
      style={style} 
      /> 
     </div> 
     </div> 
    ); 
    } 
} 

ReactDOM.render(<InputRange />, document.getElementById('root')) 

答えて

2

本当に賢いUIです!連続

increaseStakeLimits()火災全体の時間ユーザーが右端にスライダーを保持しているので、あなたが継続的に2秒後に短い間隔にthis.stakeChangeTimeoutを変更するには、新しいsetTimeoutsを設定する(継続的this.fasterChangeStakeの新しい値を設定)しています。これらは、それらのすべてが発射されるまで、高速モードに戻ってそれを強制的に長い値に間隔をリセットするためにも、後handleRelease()試みを発射し続ける(handleRelease()clearTimeoutはそれらの1キャッチ。)あなたはこの問題を解決することができ

if (!this.fasterChangeStake) { 
    this.fasterChangeStake = setTimeout(() => { 
    this.stakeChangeTimeout = this.FAST_STAKE_CHANGE_TIMEOUT; 
    this.fasterChangeStake = false; // <-- also do this in handleRelease() after clearing the timeout 
    }, 2000); 
} 

https://codepen.io/anon/pen/OgmMNq?editors=0010

:一度だけそのタイムアウトを設定することにより、
関連する問題