2016-04-12 8 views
0

Мне нужна кнопка, которую можно нажать один раз, чтобы выполнить одну команду. Но также нужно удерживать кнопку и выполнять команду несколько раз, удерживая кнопку. Я использую AngularJs (хотя я не думаю, что это связано с проблемой)js угловая кнопка hold loop failing

Что было до сих пор:

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

Это своего рода работа перед тем, как я использовал этот параметр «направление». До того, как я использовал arguments.callee в setTimeout, но когда я посмотрел, как передать аргумент с этой функцией, я замечаю, что использование 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

Я использовал следующую функцию внутри директивы некоторое время назад. Я создал его с учетом следующего:

Функция может содержать три отдельные функции обратного вызова. «Короткая» обратная связь вызывается одним щелчком мыши. При удержании кнопки короткий обратный вызов вызывается повторно. Когда вы держите кнопку нажатой, «длинный» обратный вызов срабатывает повторно. В конце, когда пользователь перестанет нажимать, будет запущен третий «заключительный» обратный вызов.

Это не может быть точное решение вашей проблемы, но, возможно, это будет вдохновлять и немного помочь вам :) Удачи.

/** 
    * 
    * @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, 1000) в setTimeout(loop('Up'), 1000)

Я не давал функции как параметр, но выполняющий функцию и возвращающий значение в качестве параметра.

я должен был сделать:

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

 Смежные вопросы

  • Нет связанных вопросов^_^