2017-12-25 25 views
-1

기본적으로 버튼을 마우스로 누르고있는 동안 여러 번 다시 버튼을 수행하려고합니다.버튼을 길게 클릭하면 많은 즉각적인 클릭이 발생합니다.

슬라이더가있는 버튼에이 기능이 필요합니다. 지금, 예를 들어 "슬라이더 늘리기"와 같은 버튼을 클릭하면 슬라이더가 1 단계 증가하지만 지금은 해당 버튼을 길게 누르면 슬라이더를 여러 단계로 늘릴 수 있습니다.

어떻게하면됩니까?

+4

정확하게 작동하지 않는다는 설명이 없으면 절대로 "작동하지 않습니다"라는 문구를 사용하지 마십시오. 그것은 오류를 던지고 있습니까? 어느? 잘못된 결과가 나오고 있습니까? 어느? 무한 루프가 진행되고 있습니까? 브라우저가 작동하지 않습니까? 컴퓨터에 불을 붙 였나요? 우리는 이미 그것이 작동하지 않는다는 것을 알고 있습니다. 그랬다면 여기에 게시하지 않을 것입니다. 다음 과제에 대해 행복하게 작업 할 것입니다. – Amadan

+1

예제 코드는 다음과 같습니다. https://jsfiddle.net/khrismuc/6x5j4ej2/ –

답변

2

귀하의 do 루프는 여러 번 1000 밀리 수 있으며, mouseleavemouseup 핸들러 기회가 루프를 통해 실행이 완료 될 때까지 mousedown 핸들러를 기다리고 their events are sitting in the message queue 때문에 실행 결코 등을 실행합니다.

루프는 몇 천 개 시간 초과를 설정하여 최소 200 ms 후에 실행됩니다. 이 시간 초과는 window's click handler is being called, not your button's이므로 게시 한 코드를 사용하여 실제로 아무 것도하지 않습니다.

start이 검사되기 전에 유효한 시간으로 재설정되기 때문에 mouseleavemouseup 처리기는 본질적으로 아무 것도 수행하지 않습니다.

어떻게 해결할 수 있습니까?

우리가 원하는 두 가지 지연이 있습니다. 처음 클릭과 슬라이더가 처음 증가 할 때 사이의 1000ms 지연과 슬라이더가 증가 할 때 200ms 지연이 있습니다. 사용자가 처음 1000ms 동안 취소하면 Google은이를 한 번의 클릭으로 계산합니다. 반복이 시작된 후 사용자가 취소하면 클릭으로 계산해서는 안됩니다. ("취소"는 마우스 버튼을 놓거나 버튼에서 커서를 옮기는 것으로 정의 할 것입니다. 즉, UI 버튼 위로 마우스 버튼을 누르고 커서를 끌 경우 클릭으로 계산되지만 코드는 더 간단합니다.)

1000ms 후, 200ms마다 슬라이더가 증가하는 간격을 설정하는 시간 제한을 설정하여 지연을 설정할 수 있습니다. 때문에 우리는 사양의 마지막 줄의 슬라이더 증가에 대한 click 이벤트를 사용하지 않을 : 반복 시작 후 사용자가 취소

경우, 우리는 클릭과 같은 것을 계산하지 않아야합니다.

function startLongClick (e) { 
    window.setTimeout(() => { 
    increaseSlider(); 
    window.setInterval(() => { 
     increaseSlider(); 
    }, 200); 
    }, 1000); 
} 
$('#button').on('mousedown', startLongClick); 

우리는 먼저 슬라이더 있도록 제한 시간에 increaseSlider()에 첫 번째 통화를 넣어 :

그래서 우리는 슬라이더 증가 코드를 (좋은 연습 어쨌든입니다) 자신의 기능, increaseSlider()을주지 1200이 아닌 처음 클릭 후 1000ms가 증가합니다. arrow functions don't redefine this이기 때문에 시간 제한 및 간격에 화살표 기능을 사용하므로 필요한 경우 <button> 트리거를 참조 할 수 있습니다.코드가 지금처럼

I can't stop it!

은 버튼 한 번의 클릭 그것을 중지 어떠한 방식으로, 전체 장기 클릭 프로세스를 시작합니다. 프로세스를 중지한다는 것은 시간 초과 및 간격을 중지하는 것을 의미하며, 우리는 window.clearTimeout() 또는 window.clearInterval()과 같은 작업을 수행 할 수 있습니다 (이들은 동일한 기능이므로 아무에게도 말하지 마십시오). 우리는 setTimeout()setInterval()이 우리에게주는 ID에 꽉해야합니다,하고는 mouseupmouseleave 핸들러에 취소 :

let intervalId; 
let timeoutId; 

function startLongClick (e) { 
    timeoutId = window.setTimeout(() => { 
    increaseSlider(); 
    intervalId = window.setInterval(() => { 
     increaseSlider(); 
    }, 200); 
    }, 1000); 
} 

function cancelLongClick() { 
    window.clearInterval(intervalId); 
    window.clearTimeout(timeoutId); 
} 

$('#button').on('mousedown', startLongClick); 
$('#button').on('mouseup', cancelLongClick); 
$('#button').on('mouseleave', cancelLongClick); 

무엇 짧은 클릭에 대한 있습니까?

단 한 가지 예외를 제외하면 버튼은 우리가 원하는 것을하고 있습니다. 즉, click 핸들러를 사용하지 않고 짧은 클릭은 아무 것도하지 않으며 increaseSlider()이 호출되기 전에 시간 초과가 해제됩니다. mousedown 이벤트가 발생한 후 시간 초과가 발생하기 전에 취소 이벤트가 발생하면 짧은 클릭이 등록되어야합니다. timeoutId 때문에 mousedown 이벤트 전에 정의되지 않는다 우리는 우리가 시간 제한에에 undefined을 할당하고 우리가 짧은 클릭 등록 여부를 결정하는 데 사용할 수 있습니다, 시간 제한 화재 일단 필요하지 않습니다 :

let intervalId; 
let timeoutId; 

function startLongClick (e) { 
    timeoutId = window.setTimeout(() => { 
    timeoutId = undefined; 
    increaseSlider(); 
    intervalId = window.setInterval(() => { 
     increaseSlider(); 
    }, 200); 
    }, 1000); 
} 

function cancelLongClick() { 
    window.clearInterval(intervalId); 
    if (timeoutId) { 
    increaseSlider(); 
    window.clearTimeout(timeoutId); 
    timeoutId = undefined; 
    } 
} 

$('#button').on('mousedown', startLongClick); 
$('#button').on('mouseup', cancelLongClick); 
$('#button').on('mouseleave', cancelLongClick); 

을 우리 짧은 클릭 코드에서도 timeoutId ~ undefined을 설정하십시오. 그렇지 않으면 마우스를 짧게 클릭 한 후 버튼을 누를 때마다 증가가 트리거됩니다.

더 많은 버튼!

코드는 작동하지만 두 개의 전역 변수가 필요하며 특정 버튼에 대해 하드 코딩되어 있습니다. 의는 범용으로 바꿀 수 있도록 jQuery 플러그인 * : 무슨

(($) => { 
 
    $.fn.repeatingClick = function (callback, delay = 500, interval = 200) { 
 
    return this.each(function() { 
 
     let intervalId; 
 
     let timeoutId; 
 
     function startLongClick (e) { 
 
     timeoutId = window.setTimeout(() => { 
 
      timeoutId = undefined; 
 
      callback.call($(this), e); 
 
      intervalId = window.setInterval(() => { 
 
      callback.call(this, e); 
 
      }, interval); 
 
     }, delay); 
 
     } 
 
     function cancelLongClick (e) { 
 
     window.clearInterval(intervalId); 
 
     if (timeoutId) { 
 
      callback.call(this, e); 
 
      window.clearTimeout(timeoutId); 
 
      timeoutId = undefined; 
 
     } 
 
     } 
 
     $(this).on('mousedown', startLongClick); 
 
     $(this).on('mouseup', cancelLongClick); 
 
     $(this).on('mouseleave', cancelLongClick); 
 
    }); 
 
    } 
 
})(jQuery); 
 

 
function modifySlider (e) { 
 
    let modifier = Number($(this).data('change')); 
 
    $('progress').attr('value', Number($('progress').attr('value')) + modifier); 
 
} 
 

 
$('button').repeatingClick(modifySlider);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<button id="dec" data-change="-1">&minus;</button> 
 
<progress value="25" max="50"></progress> 
 
<button id="inc" data-change="1">+</button>

을 변경된? callback 매개 변수와 callback.call($(this), e)increaseSlider()

  • 대체 통화. 이 방법으로 모든 함수를 콜백으로 사용할 수 있으며 시간 제한에서 화살표 함수를 사용 했으므로 Function.callthis과 함께 사용하여 콜백의 트리거 요소에 액세스 할 수 있습니다.
  • 더 일반적인 용도로 시간 초과 및 간격의 지연을 delayinterval으로 매개 변수화했습니다.
  • 새로운 jQuery 함수 $.repeatingClick()에 모든 것을 집어 넣으십시오. jQuery 객체는 개별 요소뿐만 아니라 컬렉션을 나타낼 수 있으므로 $.each() 호출에서 원래 코드를 래핑하여 각 요소에 개별적으로 액세스합니다. 또한 jQuery 객체를 일반적인 스타일로 반환합니다. 두 개의 버튼 그래서 우리는 동일한 코드를 모두 제공 할 수 있습니다 사용자에게 실제 금액에 대한 data- 속성을 사용하여 (<progress>) '슬라이더'의 값을 수정할 :

나머지는이 응용 프로그램에 따라 다릅니다.

* 이전에 jQuery 플러그인을 작성한 적이 없습니다. 핵심 로직을 둘러싼 대부분의 코드는 OP가 원하는 거의 것을 수행하는 jQuery 플러그인 인 jquery-longpress에서 바로 시작되었습니다.

1

시간을 수동으로 계산하는 대신 간격을 사용해보십시오. 이 체크 아웃 :

var value = 0 
 
var addval; 
 
var press = false; 
 

 
$('#button').on('mousedown', function (e) { 
 
\t press = true; 
 
\t increaseValue(); 
 
\t return false; 
 
}); 
 

 

 
$('#button').on('mouseleave', function (e) { 
 
    clearInterval(addval); 
 
\t return false; 
 
}); 
 

 
$('#button').on('mouseenter', function(e) { 
 
\t if (press) 
 
\t \t increaseValue(); 
 
}); 
 

 
$('#button').on('mouseup', function (e) { 
 
\t press = false; 
 
    clearInterval(addval); 
 
\t return false; 
 
}); 
 

 
function increaseValue() { 
 
\t addval = setInterval(function(){ 
 
\t \t value++; 
 
\t \t $("#counter").text(value); 
 
\t }, 100); 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<button id="button">Press me</button> 
 
<div id="counter">0</div>

당신은 시간 간격을 변경하여 속도를 조정할 수 있습니다.