setTimeout / clearTimeout 문제


103

예를 들어 시작 페이지로 이동할 페이지를 만들려고합니다. 10 초 동안 활동이 없습니다 (사용자가 아무 곳도 클릭하지 않음). 나머지는 jQuery를 사용하지만 테스트 기능의 설정 / 지우기는 순수한 자바 스크립트입니다.

내 좌절감에 나는 페이지를 클릭 할 때 호출 할 수 있기를 바랐던이 기능과 같은 것을 끝냈다. 타이머는 정상적으로 시작되지만 클릭시 재설정되지 않습니다. 함수가 처음 10 초 내에 5 번 호출되면 5 개의 경고가 표시됩니다 ... no clearTimeout ...

function endAndStartTimer() {
    window.clearTimeout(timer);
    var timer;
    //var millisecBeforeRedirect = 10000; 
    timer = window.setTimeout(function(){alert('Hello!');},10000); 
}

트릭을 수행 할 코드 줄이있는 사람이 있습니까? -클릭 중지, 재설정 및 타이머 시작. -타이머가 맞았을 때. 10 초가 뭔가를합니다.

답변:


226

함수 timer 외부 에서 선언해야 합니다. 그렇지 않으면 각 함수 호출에서 완전히 새로운 변수를 얻습니다.

var timer;
function endAndStartTimer() {
  window.clearTimeout(timer);
  //var millisecBeforeRedirect = 10000; 
  timer = window.setTimeout(function(){alert('Hello!');},10000); 
}

이 필요하기 때문에 플러스 1 하나,이 경우, 제한 시간 통화 시간이 초과되기 전에, 그래서 그것을 피하는 후드가 두 번 호출 할 수있는 변수를 취소합니다
디에고 Favero

46

문제는 timer변수가 로컬이고 각 함수 호출 후 해당 값이 손실 된다는 것 입니다.

당신은 그것을 유지해야합니다, 당신은 그것을 함수 외부에 놓을 수 있습니다. 또는 변수를 전역으로 노출하고 싶지 않다면, 클로저에 저장할 수 있습니다 . 예 :

var endAndStartTimer = (function () {
  var timer; // variable persisted here
  return function () {
    window.clearTimeout(timer);
    //var millisecBeforeRedirect = 10000; 
    timer = window.setTimeout(function(){alert('Hello!');},10000); 
  };
})();

15

타이머는 함수에 대한 지역 변수이기 때문입니다.

함수 외부에서 만들어보십시오.


6

반응에서 이것을 사용하는 방법 :

class Timeout extends Component {
  constructor(props){
    super(props)

    this.state = {
      timeout: null
    }

  }

  userTimeout(){
    const { timeout } = this.state;
    clearTimeout(timeout);
    this.setState({
      timeout: setTimeout(() => {this.callAPI()}, 250)
    })

  }
}

예를 들어 사용자가 입력을 중지 한 후에 만 ​​API를 호출하려는 경우 유용합니다. userTimeout 함수는 onKeyUp을 통해 입력에 바인딩 될 수 있습니다.


1
이것이 제가 몇 시간 동안 찾고 있던 것입니다. 감사합니다. 이런 종류의 결과가 발생하는 더 나은 방법이 있는지 궁금합니다.
Nikasv 2017

1
@nikasv 조절 및 디 바운싱은 두 가지 대안입니다. medium.com/@_jh3y/…
zero_cool

2

이것이 좋은 코딩 규칙을 위반하는지 확실하지 않지만 일반적으로 다음과 같이 나옵니다.

if(typeof __t == 'undefined')
        __t = 0;
clearTimeout(__t);
__t = setTimeout(callback, 1000);

이렇게하면 함수에서 타이머를 선언 할 필요가 없습니다.

편집 : 이것은 또한 각 호출에서 새 변수를 선언하지 않지만 항상 동일하게 재활용합니다.

도움이 되었기를 바랍니다.


0

이것은 잘 작동합니다. 보류 이벤트를 처리하기 위해 만든 관리자입니다. 보류 및 놓을 때 이벤트가 있습니다.

function onUserHold(element, func, hold, clearfunc) {
    //var holdTime = 0;
    var holdTimeout;

    element.addEventListener('mousedown', function(e) {
        holdTimeout = setTimeout(function() {
            func();
            clearTimeout(holdTimeout);
            holdTime = 0;
        }, hold);
        //alert('UU');
    });

    element.addEventListener('mouseup', clearTime);
    element.addEventListener('mouseout', clearTime);

    function clearTime() {
        clearTimeout(holdTimeout);
        holdTime = 0;
        if(clearfunc) {
            clearfunc();
        }
    }
}

요소 매개 변수는 보유하고있는 매개 변수입니다. func 매개 변수는 hold 매개 변수에 의해 지정된 밀리 초 동안 유지 될 때 발생합니다. clearfunc 매개 변수는 선택 사항이며이 매개 변수가 주어지면 사용자가 요소를 놓거나 떠나면 실행됩니다. 원하는 기능을 얻기 위해 몇 가지 해결 방법을 수행 할 수도 있습니다. 즐겨! :)


0

드롭 다운 메뉴에 Jquery를 사용하는 실제 예제! #IconLoggedinUxExternal 위에 마우스를 올려 놓으면 div # ExternalMenuLogin이 표시되고 시간 제한을 설정하여 div # ExternalMenuLogin을 숨 깁니다.

div # ExternalMenuLogin 위에 마우스를 올리면 시간 초과가 취소됩니다. div # ExternalMenuLogin에서 마우스 아웃하면 시간 제한을 설정합니다.

여기서 요점은 항상 시간 제한을 설정하기 전에 clearTimeout을 호출하여 이중 호출을 피하는 것입니다.

var ExternalMenuLoginTO;
$('#IconLoggedinUxExternal').on('mouseover mouseenter', function () {

    clearTimeout( ExternalMenuLoginTO )
    $("#ExternalMenuLogin").show()
});

$('#IconLoggedinUxExternal').on('mouseleave mouseout', function () {

    clearTimeout( ExternalMenuLoginTO )    
    ExternalMenuLoginTO = setTimeout(
        function () {

            $("#ExternalMenuLogin").hide()

        }
        ,1000
    );
    $("#ExternalMenuLogin").show()
});

$('#ExternalMenuLogin').on('mouseover mouseenter', function () {

    clearTimeout( ExternalMenuLoginTO )
});
$('#ExternalMenuLogin').on('mouseleave mouseout', function () {

    clearTimeout( ExternalMenuLoginTO )
    ExternalMenuLoginTO = setTimeout(
        function () {

            $("#ExternalMenuLogin").hide()

        }
        ,500
    );
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.