2016-04-12 14 views
0

Tek bir komutu yürütmek için bir kez basılabilen bir düğmeye ihtiyacım var. Ancak düğmeyi basılı tutup düğmeyi basılı tutarken komutu birden çok kez çalıştırmak da mümkün olmalıdır.js açısal düğme tutma döngüsü arızalı

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

ve denetleyicisi: nazik

$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); 
     } 

It ben şimdiye kadar vardı ne (Ben sorunla ilgili olduğunu düşünmüyorum rağmen)

angularjs kullanıyorum Bu 'yön' parametresini kullanmadan önce çalışma. SetTimeout içinde arguments.callee kullanılmadan önce, ancak bu işlevin bir argümanı nasıl geçeceğine baktığımda, arguments.callee kullanımının kaldırıldığını fark ettim (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee). O zamandan beri 'Maksimum çağrı yığını boyutu aşıldı' hataları alıyorum.

+1

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

+0

@ CoderHawk, bu soruyu gördüm ve ilk çözümüme ilham verdim. Ancak direktifleri kullanmak başka bir yaklaşımdır. –

cevap

0

Bir süre önce bir yönerge içinde aşağıdaki işlevi kullandım. Aşağıdakileri göz önünde bulundurarak oluşturdum:

Bu işlev üç ayrı geri arama işlevi taşıyabilir. Tek bir tıklamayla "kısa" geri çağırma çağrılır. Düğmeyi basılı tutarken, kısa geri arama tekrar tekrar aranır. Düğmeyi basılı tuttuğunuzda, "uzun" geri çağırma tekrar tekrar tetiklenir. Sonunda, kullanıcının durması durduğunda, üçüncü bir "son" geri çağırma işlemi başlatılacaktır.

Sorununuza tam bir çözüm olmayabilir, ancak belki size ilham verecek ve size biraz yardımcı olacaktır :) İyi şanslar.

/** 
    * 
    * @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); 
    } 
}; 

Bu fonksiyon ile bir elemana bağlı olan aşağıdaki:

/** 
* 
* @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

Bu zarar vermedi parametredir: setTimeout(loop('Up'), 1000)

için

setTimeout(loop, 1000) değiştirirken

Fonksiyonu vermiyordum Bir parametre olarak, ancak işlevi yürütmek ve dönüşü parametre olarak vermek.

Ben yapmalıydım

:

promis = setTimeout(function(){ loop('Up') },1000);