초보자입니다
10
2019-03-15 22:17:09
6
161

자바를 공부중인데 문제가있습니다 ㅠㅠ(setInterval)


<!DOCTYPE html>


<html>

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style media="screen">
    *{
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    .container{
      width: 960px;
      margin: 10px auto;
    }

    .bar{
      width: 100%;
      background-color: rgba(167,167,167,0.3);
    }

    #gage{
      width: 0;
      background-color : green;
    }

    p{
      padding: 20px;
      color: #fff;
      font-weight: bold;
    }

    button{
      border: 1px solid;
      padding: 20px 30px;
      font-weight: bold;
      background-color: #fff;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="bar">
      <div id="gage">
        <p id="p"></p>
      </div>
    </div>
    <br>
    <button type="button" onclick="Me()">Click Me</button>
  </div>
</body>
<script type="text/javascript">
  function Me() {
    var gage = document.getElementById("gage");
    var p = document.getElementById("p");
    var width = 1;
    var set = setInterval(key, 10);
    var set1 = setInterval(key1, 500);

    function key() {
      if (width >= 50) {
        if (width == 50) {
          confirm("실행");
          console.log(width);
        } else {
          clearInterval(key);
        }
      } else {
        width++;
        gage.style.width = width + "%";
        p.innerHTML = width + "%";
      }
    }

    function key1() {
      if (width >= 100) {
        clearInterval(key1);
      } else {
        width++;
        gage.style.width = width + "%";
        p.innerHTML = width + "%";
      }
    }
  }
</script>

</html>

제가 이런 코드를 짰습니다.

50퍼가 되면 실행 이라는 confirm을 넣고 실행창이 뜨면 확인누르고 50퍼 이상부터는 실행중이라 가정시 속도가 느리게 퍼센트가 올라가는 구조로 짜봤는데요.

이게 var set = setInterval(key, 10);

속도를 10으로 하면 한번만 나오는데 수치를 바꾸면 여러번 나옵니다 ㅠㅠ..

또는 width값을 바꿔도 여러번 confirm이 실행 되는데 그 이유를 도저히 모르겠습니다 ㅠ

왜그럴까요?
0
0
  • 답변 6

  • rezigrene
    637
    2019-03-15 23:47:08 작성 2019-03-15 23:49:21 수정됨

     clearInterval(key); (×)

     clearInterval(set); (o)



    그리고 ...


    자바 (×)

    자바스크립트 (o)



    0
  • 초보자입니다
    10
    2019-03-16 00:06:34

    이 글을 적고 이후에 코드수정을 해봤는데 변수값으로 넣어줘도 똑같네요 ...ㅠ

    0
  • 배우고싶은이
    195
    2019-03-16 01:21:06

    변수를 전역변수로~~

    현재는 함수내의 지역변수죠?

    0
  • rezigrene
    637
    2019-03-16 01:22:22

    그런데 여러번 나온다는게 의미가 무었인가요?

    0
  • rezigrene
    637
    2019-03-16 03:06:55

    제가 문제 확인을 너무 대충했었네요 10 -> 11로 바꾸니까 무얼 말씀하시는지 알겠습니다.


    1. setInterval은 confirm 창이 뜬뒤에도 백그라운드에서 계속하여 실행된다.

    2. width == 50 인 동안에는 key()는 confirm 창을 띄우는 로직을 실행한다. 

    3. key1()에 의해서 값이 바뀌지 않으면 영원히 width == 50 이다.


    10: 500 인 경우 비율이 다행히 잘 맞아 첫번째 confirm 직후에 바로 key1()이 실행되어 width == 51 이되어 별일이 없었던것이고,

    11: 500 인경우 첫번째 confirm이후 key1() 이 실행되기까지 40회이상 key()를 반복해야 key1() 차례가 오기 떄문에 그렇습니다.


    해결책은 아래와 같습니다.

    1. confirm앞에 clearInterval 을 넣어 Interval을 미리 종료시킨다.  

    function Me() {
    var gage = document.getElementById("gage");
    var p = document.getElementById("p");
    var width = 1;
    var set = setInterval(key, 11);
    var set1 = setInterval(key1, 500);
    function key() {
    if (width >= 50) {
    if (width == 50) {
    clearInterval(set);
    confirm("실행");
    console.log(width);
    } else {
    clearInterval(set);
    }
    } else {
    width++;
    gage.style.width = width + "%";
    p.innerHTML = width + "%";
    }
    }

    function key1() {
    if (width >= 100) {
    clearInterval(set1);
    } else {
    width++;
    gage.style.width = width + "%";
    p.innerHTML = width + "%";
    }
    }
    }


    2. confirm동안은  코드의 진행이 멈출수 있도록 setInterval 대신 setTimeout을 쓴다.

    function Me() {
    var gage = document.getElementById("gage");
    var p = document.getElementById("p");
    var width = 1;
    setTimeout(key, 11);
    setTimeout(key1, 500);
    function key() {
    if (width >= 50) {
    if (width == 50) {
    confirm("실행");
    console.log(width);
    } else {
    //clearInterval(key);
    }
    } else {
    width++;
    gage.style.width = width + "%";
    p.innerHTML = width + "%";
    setTimeout(key, 10);
    }
    }

    function key1() {
    if (width >= 100) {
    //clearInterval(key1);
    } else {
    width++;
    gage.style.width = width + "%";
    p.innerHTML = width + "%";
    setTimeout(key1, 500);
    }
    }
    }



    3. ??

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style media="screen">
    *{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    }

    .container{
    width: 960px;
    margin: 10px auto;
    }

    .bar{
    width: 100%;
    background-color: rgba(167,167,167,0.3);
    }

    #gage{
    width: 0;
    background-color : green;
    }

    p{
    padding: 20px;
    color: #fff;
    font-weight: bold;
    }

    button{
    border: 1px solid;
    padding: 20px 30px;
    font-weight: bold;
    background-color: #fff;
    }
    </style>
    </head>

    <body>
    <div class="container">
    <div class="bar">
    <div id="gage">
    <p id="p"></p>
    </div>
    </div>
    <br>
    <button type="button" onclick="progressBar.start()">Click Me</button>
    </div>
    </body>
    <script type="text/javascript">
    const progressBar = {
    start() {
    this.progress = 0;
    this.confirmed = false;
    let time = new Date().getTime();
    this.time = time;
    setTimeout(() => { this.step(time); }, 10);
    },
    step(time) {
    let interval = this.progress > 50 ? 500 : 10;
    if (!this.confirmed && this.progress >= 50) {
    this.confirmed = true;
    confirm("실행");
    }
    this.progress++;
    this.render();
    if (this.progress < 100 && time == this.time) {
    setTimeout(() => { this.step(time); }, interval);
    }
    },
    render() {
    let gage = document.getElementById("gage");
    let p = document.getElementById("p");
    gage.style.width = this.progress + "%";
    p.innerHTML = this.progress + "%";
    }
    }
    </script>
    </html>
    0
  • 초보자입니다
    10
    2019-03-16 11:01:30 작성 2019-03-16 11:14:27 수정됨

    와.. 감사합니다!! 3개다 작동이 너무 잘되네요. 어제 그렇게 붙잡았었는데 .


    확실히 순서와 위치 그리고 셋타임아웃을 적절히 활용해야된다는걸 느꼈네요. 정말 감사합니다.


    이 코드로 공부를 해야겠습니다..


    마지막 let.. let도 공부해야지요 ..ㅠ... 정말 감사합니다.!

    0
  • 로그인을 하시면 답변을 등록할 수 있습니다.