[JavaScript] 더블 클릭 이벤트 방지[JavaScript] 더블 클릭 이벤트 방지

Posted at 2018. 12. 29. 17:32 | Posted in JavaScript & jQuery/JavaScript
반응형




참고 : http://cofs.tistory.com/270




해당 코드는 제목대로 사용자의 더블 클릭 이벤트가 발생하였을 경우 예외처리가 가능하다.


그렇지만 윈도우 바탕화면의 실행 아이콘을 더블 클릭하는것과 같이.


빠르게 더블 클릭하는것을 예외 처리하는 코드가 아니라는것을 우선 밝혀두는 바이다.


그저 그런 이벤트를 막기위한 한가지 꼼수라고 생각하고 포스팅을 보길 바란다.







■ 짝수 클릭의 경우 예외 처리하기




특정 이벤트 실행시 더블 클릭을 방지하기 위해서 제작되었다.


위 코드의 원본은 http://cofs.tistory.com/270 포스팅을


현재 필자가 진행한 프로젝트에 맞게 수정한 내용이다.




해당 코드를 사용시 주의할 점이 존재하기에 우선 그 부분을 먼저 설명하고자 한다.


# 주의사항


      진짜 더블 클릭을 예외처리하는 코드가 아니다,

         실제로는 짝수번째의 클릭시 이벤트를 막는다.


      해당 기능은 한 페이지에서 하나의 이벤트만이 수행 가능하다.

         복수의 이벤트에서 사용하려면 추가적인 로직을 구현하는 작업이 필요하다.






# 소스 코드

<html>
<head>
<title>:: JAVASCRIPT 더블 클릭 방지 ::</title>
<script type="text/javascript">

  // 시작과 동시에 선언될 익명 선언식 함수를 사용한다.
  // 익명 선언식 함수를 사용한 이유는
  // doubleFlag 변수를 전역으로 사용하는것을 피하기 위해서다.
  (function() {

    // doubleFlag는 처음에 false로 초기화 한다.
    var doubleFlag = false;

    // 더블 클릭 함수 생성
    this.doubleCheck = function doubleCheck() {
      if(doubleFlag == true) {
        return doubleFlag;
      } else {
        doubleFlag = true;
        return false;
      }
    }

    // 더블 클릭된 이벤트가 발생이후 다시 버튼을 초기화 하기 위해 사용된다.
    this.clickInitial = function clickInitial() {
      doubleFlag = false;
    }
  })();

  // 클릭 이벤트
  function clickSubmit() {

    // 더블 클릭한 경우
    if(doubleCheck() == true) {

      alert("2번클릭");


      // 다시 정상적으로 클릭이벤트가 발생 할 수 있도록 초기화 요청
      clickInitial();
      return;
    }

    // 한번만 클릭한 경우
    else {
      alert("1번클릭");
    }
  }


</script>
</head>
<body>

    <h3>더블 클릭 이벤트 예외 처리하기</h3>

    <input type="button" onClick="clickSubmit();" value="검사"/>
</body>
</html>



# 출력 결과






반응형
//

[JavaScript] 자바스크립트에서의 Test Suite[JavaScript] 자바스크립트에서의 Test Suite

Posted at 2018. 12. 25. 17:15 | Posted in JavaScript & jQuery/JavaScript
반응형




■ 테스트 스위트란?



테스트 스위트의 주된 목적은 개별 테스트를 묶어 하나의  자원으로 제공함으로써

여러 테스트를 한 번에 실행할 수 있게 그리고 반복해서 간단히 실행할 수 있게 하는 것이다.




#01. 검증 조건


단위 테스트 프레임워크의 핵심은 검증 메서드로, 이 메서드의 이름은 일반적으로 assert( ) 이다.

해당 메서드는 항상 검증의 전제가  되는 표현 하나와 검증의 목적을 설명하는 인자를 받는다.

해당 표현 값이 ""이거나 "참 이 될 수 있는 값"이면 검증 조건을 통과하게 된다.

그렇지 않으면, 실패로 간주된다.

연관된 문구는 보통 성공 / 실패 표시와 함께 출력된다.

다음 코드에서 이 개념의 간단한 구현을 볼 수 있다.



# 소스 코드

 test_suite.php

<html>
  <head>
    <title>:: 테스트 스위트 ::</title>
    <script type="text/javascript">

      // assert() 메서드 정의
      function assert(value, desc) {
        var li = document.createElement("li");
        li.className = value ? "pass" : "fail";
        li.appendChild(document.createTextNode(desc));
        document.getElementById("results").appendChild(li);
      } // END function assert(value, desc)

      // 검증 조건을 이용해서 테스트 실행
      window.onload = function() {


        assert(true, "테스트 스위트 러닝");
        assert(false, "테스트 실패");
      } // END window.onload = function()
    </script>
    <style type="text/css">
      /* 결과를 출력할때 구분할 스타일 정의 */
      #results li.pass { color:#008000; }
      #results li.fail { color:#FF0000; }
    </style>
  </head>
  <body>
    <!-- 테스트 결과 수집 -->
    <ul id="results"></ul>
  </body>
</html>




# 출력 결과






#02. 테스트 그룹



간단한 검증 조건만으로도 유용하지만, 테스트 내용에 따라서 테스트를 그룹으로 묶을 때, 이는 정말로 유용해지기 시작한다.


단위 테스트에서, 하나의 테스트 그룹은 API나 애플리케이션에서 주로 어떤 한 메서드와 연관된 검증 조건들의 집합을 나타낸다.


또한 행위 주도 개발(behavior-driven development)을 한다면, 테스트 그룹은 태스크에 대한 검증 조건의 집합이 될 것이다.


어쨌거나 두 경우 모두, 테스트 그룹을 구현하는 방식은 거의 동일하다.



다음 테스트 스위트 예제는 테스트 그룹을 제공하고, 테스트 그룹 내에 포함된 각 검증 조건에 대한 결과는 results에 저장된다.


게다가 어떤 검증 조건이 하나라도 실패하면, 전체 테스크 그룹은 실패로 표시된다. 다음 코드의 결과는 꽤 간단하지만,


몇 단계의 동적 제어(테스트 그룹 내에 실패한 테스트가 있을경우, 테스트 그룹을 확장 / 축소하거나 필터링 하는것)는


실제로 매우 유용할 것이다.




# 소스 코드

 group_test_suite.php

<html>
  <head>
    <title>:: 테스트 그룹 구현 ::</title>
    <script type="text/javascript">

      // 익명 즉시 실행 함수 정의
      (function() {
        var results = "";
        this.assert = function assert(value, desc) {
          var li = document.createElement("li");
          li.className = value ? "pass" : "fail";
          li.appendChild(document.createTextNode(desc));
          results.appendChild(li);

          if(!value) {
            li.parentNode.parentNode.className = "fail";
          }

          return li;
        };

        this.test = function test(name, fn) {
          results = document.getElementById("results");
          results = assert(true, name).appendChild(document.createElement("ul"));
          fn();
        };
      })(); // (function())

      // 검증 조건을 이용해서 테스트 실행
      window.onload = function() {
        test("A test.", function() {
          assert(true, "첫번째 증명 성공");
          assert(true, "두번째 증명 성공");
          assert(true, "세번째 증명 성공");
        });

        test("B test.", function() {
          assert(true, "첫번쨰 테스트 성공");
          assert(false, "두번쨰 테스트 실패");
          assert(true, "세번쨰 테스트 성공");
        });

        test("C test.", function() {
          assert(null, "fail");
          assert(5, "pass");
        });
      } // END window.onload = function()
    </script>
    <style type="text/css">

      /* 결과를 출력할때 구분할 스타일 정의 */
      #results li.pass { color:#008000; }
      #results li.fail { color:#FF0000; }
    </style>
  </head>
  <body>
    <!-- 테스트 결과 수집 -->
    <ul id="results"></ul>
  </body>
</html>




# 출력 결과



위코드는 먼저 테스트한 test_suite.php 페이지의 assert( ) 함수의 로깅 구현과 크게 다르지 않다.


가장 큰 차이는 현재 테스트 그룹을 참조하는(검증 조건을 적절히 로깅하기 위한 수단인) results 변수를 포함하고 있느냐이다.


비동기 테스트 동작을 다루는 방식 역시 테스트 프레임워크의 중요한 측명가운데 하나다.







#03. 비동기 테스트



많은 개발자들이 자바스크립트 테스트 스위트 개발 중에 만나는 힘들고 복잡한 작업은 비동기 테스트다.


Ajax 요청이나 애니메이션처럼, 비동기 테스트는 예측할 수 없는 시간이 지난 후에야 결과를 받게 될 것이다.


비동기 테스트의 이러한 이슈를 다루는 작업은 오버엔지니어링이 되기 쉽상이고, 필요 이상으로 일을 복잡하게 만들기도 한다.


비동기 테스트를 다루려면 다음 단계를 따라야 한다.



    ① 동일한 비동기 연산에서 사용해야 한는 검증 조건은 같은 테스트 그룹으로 묶어야 한다.


    ② 각 테스트 그룹은 하나의 큐에 존재해야 하고, 이전 테스트 그룹이 모두 종료한 뒤에 실행되어야 한다.




이렇게, 각 테스트 그룹은 비 동기적으로 실행될 수 있다.




# 소스 코드

 asynchronous_test_suite.php

<html>
  <head>
    <title>:: 비동기 테스트 스위트 ::</title>
    <script type="text/javascript">

      // 익명 즉시 실행 함수 정의
      (function() {

        var queue = [];
        var paused = false, results;

        this.test = function(name, fn) {

          queue.push(function() {
            results = document.getElementById("results");
            results = assert(true, name).appendChild(document.createElement("ul"));
            fn();
          });

          runTest();
        };

        this.pause = function() {

          paused = true;
        }

        this.resume = function() {

          paused = false;
          setTimeout(runTest, 1);
        }

        function runTest() {

          if(!paused && queue.length) {
            queue.shift()();
            if(!paused) {
              resume();
            }
          }
        }

        this.assert = function assert(value, desc) {

          var li = document.createElement("li");
          li.className = value ? "pass" : "fail";
          li.appendChild(document.createTextNode(desc));
          results.appendChild(li);

          if(!value) {
            li.parentNode.parentNode.className = "fail";
          }

          return li;
        };
      })(); // END (function())

      // 검증 조건을 이용해서 테스트 실행
      window.onload = function() {

        test("비동기 테스트 #01.", function() {
          pause();
          setTimeout(function() {
            assert(true, "첫번째 테스트 성공");
            resume();
          }, 1000);
        });

        test("비동기 테스트 #02.", function() {
          pause();
          setTimeout(function() {
            assert(false, "두번째 테스트 실패");
            resume();
          }, 1000);

          test("비동기 테스트 #03.", function() {
            pause();
            setTimeout(function() {
              assert(true, "세번째 테스트 성공");
              resume();
            }, 1000);
          });
        });
      } // END window.onload = function()
    </script>
    <style type="text/css">

      /* 결과를 출력할때 구분할 스타일 정의 */
      #results li.pass { color:#008000; }
      #results li.fail { color:#FF0000; }
    </style>
  </head>
  <body>
    <!-- 테스트 결과 수집 -->
    <ul id="results"></ul>
  </body>
</html>





# 출력 결과




asynchronous_test_suite.php 페이지에는 외부에서 사용 가능한 test( ), pause( ), resume( ) 함수가 세 개가 있다.


이 세 함수는 다음 특성을 따른다.




    ① test( fn )


        -. 다수의 검증 조건을 가지고 있는 함수를 인자로 받고, 이 함수를 테스트 실행을 위한 큐에 저장한다.

        -. 함수가 가지고 있는 검증 조건은 동기나 비동기로 실행될 것이다.



    ② pause( )


        -. test( ) 함수 안에서 실행된다.

        -. 현재 테스트 그룹의 실행이 완료될 때까지, 테스트 스위트에 실행 중인 전체  테스트를 정지하라고 알려준다.



    ③ resume( )


        -. test( ) 함수를 재개하고, 이전 코드가 오래 실행되어 전체 코드가 멈추는 것을 방지하기 위해서

          잠시 동안의 딜레이를 준 다음 테스트를 실행한다.





내부적인 구현 함수는 runTest( ) 이며 테스트가 큐에 저장되거나 빠질 때 호출된다.


테스트 스위트가 현재 정지되지 않았는지를 체크하고, 큐 안에 테스트가 있다면, 테스트를 큐에서 빼서 실행을 시도한다.


게다가 테스트 그룹의 실행이 종료된 후에, runTest( )는 테스트 스위트가 현재 정지되어 있는지를 검사하고,


그렇지 않다면(테스트 그룹 안에 비동기 테스트만 실행된고 있다면),


runTest( )는 다음 테스트 그룹을 실행하기 시작한다.





반응형
//

[jQuery] Mobile Web 사용시 KEYBOARD 이벤트 체크[jQuery] Mobile Web 사용시 KEYBOARD 이벤트 체크

Posted at 2018. 11. 17. 13:14 | Posted in JavaScript & jQuery/jQuery
반응형



■ 모바일 웹 키보드 ON / OFF 여부 체크하기




#01. 안드로이드(Android)에서 키보드 이벤트 체크


# 소스코드

<html>
<head>
<title>:: MOBILE 키보드 체크 ::</title>
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1,user-scalable=no"/>
<link rel="stylesheet" type="text/css" href="http://code.jquery.com/mobile/git/jquery.mobile-git.min.css"/>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/mobile/git/jquery.mobile-git.min.js"></script>
<script type="text/javascript">
  jQuery(window).load(function() {
     
      // 처음 시작시 화면의 사이즈 값을 가진다.
      var originalSize = jQuery(window).width() + jQuery(window).height();
     
      // 창의 사이즈 변화가 일어났을 경우 실행된다.
      jQuery(window).resize(function() {
         
        // 처음 사이즈와 현재 사이즈가 변경된 경우
        // 키보드가 올라온 경우
        if(jQuery(window).width() + jQuery(window).height() != originalSize) {
           
          alert("가상 키보드가 오픈 되었습니다."); 
        }
       
        // 처음 사이즈와 현재 사이즈가 동일한 경우
        // 키보드가 다시 내려간 경우
        else {
           
          alert("가상 키보드의 사용지 종료되었습니다.");
        }
      });
    });
</script>
</head>
<body>
<div data-role="page">
    <div data-role="header" data-position="fixed">
        <h1>:: MOBILE 키보드 체크 ::</h1>
    </div>
     <div data-role="content">
        <div data-role="fieldcontain">
            <label for="textinput">ID</label>
            <input type="text" name="id_input" id="id_input"/>
        </div>
        <div data-role="fieldcontain">
            <label for="textinput">Password</label>
            <input type="text" name="password_input" id="password_input"/>
        </div>
        <div class="ui-grid-a">
            <div class="ui-block-a">
                <input type="submit" value="로그인"/>
            </div>
            <div class="ui-block-b">
                <input type="reset" value="로그아웃"/>
            </div>
        </div>
    </div>
    <div data-role="footer" data-position="fixed">
        <h1>FOOTER</h1>
    </div>
</div>
</body>
</html>




# 출력결과

  키보드 오픈

  키보드 종료










#02. 아이폰(iOS)에서 키보드 이벤트 체크



준비중



반응형
//

[JavaScript] 저장소 사용하기[JavaScript] 저장소 사용하기

Posted at 2018. 9. 7. 15:51 | Posted in JavaScript & jQuery/JavaScript
반응형





localStorage를 사용한 저장소 기능 사용하기



-. 기존의 자바스크립트는 쿠키를 사용하는 방법 이외에도 수많은 방법을 사용해 데이터를 저장하고자 노력했다.

-. 이전에는 플래시 저장소를 사용하거나 각각의 브라우저에 존재하는 특수한 저장소를 사용했다.

-. 데이터를 오래 지속하는 것은 애플리케이션을 만들 때 꼭 필요한 기능이므로 HTML5부터는 저장소 기능을 기본으로 제공한다.

-. 저장소는 웹 브라우저를 삭제하지 않는이상 데이터를 영구적으로 저장한다.



:: 저장소 기능을 지원하는 브라우저 ::

 인터넷 익스플러(Internet Explorer)

 8 이상

 파이어 폭스(Fire Fox)

 3.5 이상

 사파리(Safari)

 4.0 이상

 크롬(Chrome)

 4.0 이상

 오페라(Opera)

 10.5 이상



# 소스코드

<html>
<head>
<title>:: JavaScript 로컬 저장소 ::</title>
<script language="javascript">

    document.addEventListener("DOMContentLoaded", function() {

        if(window.localStorage) {

            // 해당 예제를 실행하기전 이전 clear( ) 메서드를를 사용하여 작성했던 저장소의 내용을 전부 삭제한다.
            localStorage.clear();
        }
        else {
            alert("로컬 저장소를 사용할 수 없는 브라우저입니다.");
        }
    });

    function printLocalStorage() {

        var output = "";

        // div 태그에 로컬 저장소의 내용을 출력한다.
        for(var key in window.localStorage) {
            output += "<p>";


            // getItem( ) 메서드를 이용하여 key 값의 value 값을 찾는다.
            output += key + " : " + localStorage.getItem(key);
            output += "</p>";
        }

        document.getElementById("output").innerHTML = output;
    }

    function saveLocalStorage() {

        // 변수를 선언한다.
        var key = document.getElementById("key").value;
        var value = document.getElementById("value").value;

        // setItem( ) 메서드를 이용하여 value값을 로컬 저장소에 저장한다.
        localStorage.setItem(key, value);

        // 데이터를 출력한다.
        printLocalStorage();
    }
</script>
</head>
<body>
    <input type="text" id="key" value=""/>
    <input type="text" id="value" value=""/>
    <input type="button" value="저장" onClick="saveLocalStorage();"/>
    <div id="output">
        <!-- 저장된 내용을 출력할 DIV 엘리먼트 -->
    </div>
</body>
</html>




# 출력결과





localStorage 객체의 메서드


메서드 이름

설명

 setItem(key, value)

 · 로컬 저장소에 데이터를 생성한다.

 getItem(key)

 · 로컬 저장소의 데이터를 읽어온다.

 removeItem(key)

 · 로컬 저장소의 지정한 key 값의 데이터를 삭제한다.

 clear()

 · 로컬 저장소의 데이터를 전부 삭제한다.

 key(number)

 · 로컬 저장소의 특정 순서의 데이터를 읽어온다.







반응형
//