2016-04-12 17 views
0

単一のコマンドを実行するために一度押すことができるボタンが必要です。しかし、ボタンを押したまま、ボタンを押し続けて複数回コマンドを実行することも可能です。js角度ボタンホールドループが失敗する

<button type="button" 
     class="btn btn-default" 
     ng-click="ChangeSetPoint('Up')" 
     ng-mousedown="startLoopingUp()" 
     ng-mouseup="stopLoopingUp()" 
     ng-mouseleave="stopLoopingUp()"> 
     + 
</button> 

とコントローラで:種類

$scope.ChangeSetPoint = function(direction){ 
      //Stuff to actually change the setpoint 
     } 

     var looping = false; 
     var promis; 
     $scope.startLoopingUp = function(){ 
      looping = true; 
      promis = setTimeout(loop('Up'),1000);   
     } 

     var loop = function(direction){           
      $scope.ChangeSetPoint(direction); 
      if(looping){ 
       promis = setTimeout(loop(direction),300) 
      } 
     } 

     $scope.stopLoopingUp = function(){ 
      looping = false; 
      clearTimeout(promis); 
     } 

それを私は、私がこれまで持っていた何を(私はそれが問題に関連しているとは思わないが)

AngularJsを使用していますこの「方向」パラメータを使用する前の作業のsetTimeoutでarguments.calleeを使用する前に、その関数で引数を渡す方法を調べたところ、arguments.calleeの使用が推奨されませんでした(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee)。それ以来、「最大呼び出しスタックサイズを超えました」というエラーが表示されます。

+1

http://stackoverflow.com/questions/25180332/how-can-i-listen-for-a-click-and-hold-in-angularjs – CoderHawk

+0

@ CoderHawk、私​​はその質問を見て、私の最初の解決策に触発しました。しかし、ディレクティブを使用することも別の方法です。 –

答えて

0

私はディレクティブの中で次の関数を使用しています。

この関数は、3つの独立したコールバック関数を保持している可能性があります。ショートコールバックはワンクリックで呼び出されます。ボタンを保持すると、短いコールバックが繰り返し呼び出されます。ボタンを押したままにすると、「長い」コールバックが繰り返し発生します。最後に、ユーザーがプレスを停止すると、3番目の「最終」コールバックが発生します。

これはあなたの問題の正確な解決策ではないかもしれませんが、おそらくそれはインスピレーションを与え、少し助けになるでしょう:)幸いです。

/** 
    * 
    * @param {Event} evt 
    * @param {Function} shortCallback 
    * @param {Function} longCallback 
    * @param {Function} [finishCallback] optional 
    */ 
var onBtnClick = function (evt, shortCallback, longCallback, finishCallback) { 
    //prevent mobile browser from long tap behaviour (simulated right click) 
    evt.preventDefault(); 
    //only react to left mouse button or a touch event 
    if (evt.which === 1 || evt.type === "touchstart") { 
     //save 'this' context and interval/timeout IDs 
     var self = this, 
      short = { 
       timeout  : null, 
       interval : null, 
       callback : angular.isFunction(shortCallback) ? shortCallback : angular.noop 
      }, 
      long = { 
       timeout  : null, 
       interval : null, 
       callback : angular.isFunction(longCallback) ? longCallback : short.callback 
      }, 
      listener = "mouseup mouseleave touchend touchcancel", 
      // 
      cancelShort = function() { 
       $timeout.cancel(short.timeout); 
       $interval.cancel(short.interval); 
      }, 
      // 
      cancelLong = function() { 
       $timeout.cancel(long.timeout); 
       $interval.cancel(long.interval); 
      }; 

     //react to a single click 
     short.callback(); 

     //when user leaves the button cancel timeout/interval, lose focus and unbind recently bound listeners 
     self.one(listener, function (e) { 
      e.preventDefault(); 
      cancelShort(); 
      cancelLong(); 

      if (angular.isFunction(finishCallback)) { 
       finishCallback(); 
      } 

      self.blur(); 
     }); 

     //on a long click call the callback function within an interval for faster value changing 
     short.timeout = $timeout(function() { 
      short.interval = $interval(short.callback, 50, 0, false); 
     }, 300, false); 

     //when pressed even longer, cancel previous callback and fire "long" one 
     long.timeout = $timeout(function() { 
      cancelShort(); 
      long.interval = $interval(long.callback, 50, 0, false); 
     }, 1500, false); 
    } 
}; 

この関数は、次のように要素にバインドされています:

/** 
* 
* @param {String} selector 
* @param {Function} clickCallback 
* @param {Function} fastCallback 
* @param {Function} [finishCallback] optional 
*/ 
var bindEvent = function (selector, clickCallback, fastCallback, finishCallback) { 
    $element.on("mousedown touchstart", selector, function (evt) { 
     onBtnClick.call($(this), evt, clickCallback, fastCallback, finishCallback); 
    }); 
}; 
0

それが害をしたパラメータだった:setTimeout(loop('Up'), 1000)

setTimeout(loop, 1000)を変更する際

私は機能を与えていませんでしたその関数を実行して、その戻り値をパラメータとして渡します。

私が行っている必要があります。

promis = setTimeout(function(){ loop('Up') },1000); 
関連する問題