프로그래밍/자바스크립트

Javascript - 웹브라우저 별 이벤트 처리

가카리 2015. 1. 25. 21:40
반응형

1.       웹브라우저와 자바스크립트 실행환경



2.       웹브라우저 객체


위를 DOM(Document object model)이라고 함

위와 같이 document 객체로 이용해서 접근 가능


3.       HTML DOM



DOM 트리로 구성하면 오른쪽처럼 구성할 수 있음



위 메소드는 많이 사용한다.



08-01.html


<!DOCTYPE html>

<html lang="ko">

  <head>

    <meta charset="utf-8" />

    <title>08-01</title>

    <script type="text/javascript">

    

      // 주어진 노드 객체의 모든 자식노드 노드타입이 엘리먼트인 노드의 이름을 출력합니다.

      function printTags(node) {

        var tags = '';

      

        // 노드타입이 엘리먼트인지를 검사합니다.

        if (node.nodeType == Node.ELEMENT_NODE) {

          // nodeName 프로퍼티에 저장되어 있는 노드의 이름을 tags 변수에 저장합니다.

          tags += node.nodeName + '<br/>';

        }

        

        // 자식노드 객체들에 대한 NodeList 객체를 저장합니다.

        var children = node.childNodes;

        

        // NodeList 객체의 length 프로퍼티를 이용해 printTags 함수를 재귀호출 합니다.

        for (var i = 0; i < children.length; i++) {

          // printTags 함수에 NodeList 객체에 담긴 자식노드 항목들을 전달하여

          // 실행된 결과를 tags 변수에 문자열 접합연산을 통해 저장합니다.

          tags += printTags(children[i]);

        }

        

        return tags;

      }

    

      // HTML 문서가 파싱되고 외부 컨텐츠 로딩이 완료되면 브라우저는 load 이벤트를 발생하는데,

      // load 이벤트의 이벤트 핸들러로 등록된 함수가 실행됩니다. load 이벤트 핸들러에서

      // id 값이 "result" div 태그를 찾아 innerHTML 프로퍼티에 html 문자열 값을 저장합니다.

      window.onload = function() {

        var result = document.getElementById('result');

        result.innerHTML = printTags(document);             

         };

    </script>

  </head>

  <body>

    <div id="result">

    </div>

  </body>

</html>


출력 화면



4.       이벤트와 이벤트 핸들러



08-02.html


<!DOCTYPE html>

<html lang="ko">

  <head>

    <meta charset="utf-8" />

    <title>08-02</title>

    <script type="text/javascript">

      

      // 버튼 "btnAdd" 클릭하면 함수를 호출합니다.

      function add() {

        // id 속성 값이 'siteName', 'url', 'result' 엘리먼트를 찾아 참조합니다.

        var siteNameElement = document.getElementById('siteName');

        var urlElement = document.getElementById('url');

        var resultElement = document.getElementById('result');

        

        // <a></a> 엘리먼트를 생성합니다.

        var anchorElement = document.createElement('a');

        // <a href="???"></a> 엘리먼트의  href 속성값을 urlElement 저장된 값으로 대입합니다.

        anchorElement.href = urlElement.value;

        // siteNameElement 저장된 값으로 텍스트노드를 생성합니다.

        var newTextNode = document.createTextNode(siteNameElement.value);

        // <a href="???"> ???? </a> 엘리먼트의 자식노드로 방금 만든 텍스트노드를 추가합니다.

        anchorElement.appendChild(newTextNode);

        // <br /> 엘리먼트를 생성합니다.

        var brElement = document.createElement('br');

        // resultElement 자식노드로 anchorElement brElement 추가합니다.

        resultElement.appendChild(anchorElement);

        resultElement.appendChild(brElement);

        

        // 입력 필드를 초기화합니다.

        siteNameElement.value = '';

        urlElement.value = '';

      };

      

      // 버튼 "btnCancel" 클릭하면 함수를 호출합니다.

      function cancel() {

        // id 속성 값이 'siteName', 'url' 엘리먼트를 찾아 참조합니다.

        var siteNameElement = document.getElementById('siteName');

        var urlElement = document.getElementById('url');

        

        // 입력 필드를 초기화합니다.

        siteNameElement.value = '';

        urlElement.value = '';

      };

      

      // HTML 문서가 파싱되고 외부 컨텐츠 로딩이 완료되면 브라우저는 load 이벤트를 발생하는데,

      // load 이벤트의 이벤트 핸들러로 등록된 함수가 실행됩니다. load 이벤트 핸들러에서

      // id 값이 "btnAdd" "btnCancel" 버튼을 찾아 click이벤트에 대해 이벤트 핸들러 함수를 등록합니다.

      window.onload = function() {

        var btnAddElement = document.getElementById('btnAdd');

        var btnCancelElement = document.getElementById('btnCancel');

        

        btnAddElement.onclick = add;

        btnCancelElement.onclick = cancel;

      };

    </script>

  </head>

  <body>

    <form>

      <label>

        사이트 : <br />

        <input type="text" id="siteName" size="50" /><br />

      </label>

      <label>

        URL : <br/>

        <input type="text" id="url" size="50" /><br /> 

      </label>

      <input type="button" id="btnAdd" value="추가" />

      <input type="button" id="btnCancel" value="취소" />

    </form>

    <div id="result">

    </div>

  </body>

</html>



출력화면




5.       DOM 이벤트 핸들링







이벤트를 넣을때

이벤트를 지울때


08-03.html


<!DOCTYPE html>

<html lang="ko">

  <head>

    <meta charset="utf-8" />

    <title>08-03</title>

    <script type="text/javascript">

      

      // click 이벤트 발생 수행할 이벤트 핸들러 함수입니다.

      function addText() {

        var resultElement = document.getElementById('result');

        resultElement.innerHTML = '크로스 브라우징 이벤트 리스너 구현!!!';

          

      }

      

      // click 이벤트 발생 수행할 이벤트 핸들러 함수입니다.

      function clearText() {

        var resultElement = document.getElementById('result');

        resultElement.innerHTML = ''

      }

      

      // load 이벤트 발생 수행할 이벤트 핸들러 함수입니다.

      function init() {

        // id 속성 값이 'btnClick', 'btnCancel' 버튼을 찾아 크로스 브라우징 기능이 구현된

        // 이벤트 리스너 등록 함수를 사용해 click 이벤트에 대한 이벤트 핸들러 함수를 등록합니다.

        var btnClickElement = document.getElementById('btnClick');

        var btnCancelElement = document.getElementById('btnCancel');

        addListener(btnClickElement, 'click', addText);

        addListener(btnCancelElement, 'click', clearText);

      }

      

      // 크로스 브라우징을 고려해 구현한 이벤트 리스너 등록  함수입니다.

      // el : 이벤트가 발생할 HTML 요소

      // ev : 이벤트

      // handler : 이벤트 핸들러 함수

      function addListener(el, ev, handler) {

        // FireFox, Chrome 같은 IE 웹브라우저의 경우

        if (el.addEventListener) {

          el.addEventListener(ev, handler, false)

        } else { // IE 브라우저의 경우

          el.attachEvent('on' + ev, handler);

        }

      }

      

      addListener(window, 'load', init);

      

    </script>

  </head>

  <body>

    <form>

      <input type="button" id="btnClick" value="눌러주세요" />

      <input type="button" id="btnCancel" value="취소" />

    </form>

    <div id="result">

    </div>

  </body>

</html>


출력화면




6.       DOM 이벤트 격파


이벤트 전파는 버블링 단계때문에 버블링 억제가 필요할 때가 있다. 그를 위한 예제이다.


06-04.html


<!DOCTYPE html>

<html lang="ko">

  <head>

    <meta charset="utf-8" />

    <title>08-04</title>

    <style>

      .class1 {

        background-color: #adff2f;

      }

      .class2 {

        background-color: #dda0dd;

      }

    </style>

    <script type="text/javascript">

      

      // 크로스 브라우징이 적용된 이벤트 버블링 억제 함수

      function cancelBubbling(e) {

        // FireFox, Chrome 같은 IE 웹브라우저의 경우

        if (e.stopPropagation) {

          e.stopPropagation();

        } else // IE 브라우저의 경우

          window.event.cancelBubble = true;

        }

      }

      

      // click 이벤트 발생 수행할 이벤트 핸들러 함수입니다.

      function outerFunc() {

        var resultElement = document.getElementById('result');

        resultElement.innerHTML = 'outer 에서 click 이벤트 발생';

          

      }

      

      // click 이벤트 발생 수행할 이벤트 핸들러 함수입니다.

      function innerFunc(e) {

        var resultElement = document.getElementById('result');

        resultElement.innerHTML = 'inner 에서 click 이벤트 발생';

        //cancelBubbling(e);  // 상위 객체로의 이벤트 버블링을 억제합니다

      }

      

      // load 이벤트 발생 수행할 이벤트 핸들러 함수입니다.

      function init() {

        // id 속성 값이 'outer', 'inner' 영역을 찾아 크로스 브라우징 기능이 구현된

        // 이벤트 리스너 등록 함수를 사용해 click 이벤트에 대한 이벤트 핸들러 함수를 등록합니다.

        var outerElement = document.getElementById('outer');

        var innerElement = document.getElementById('inner');

        outerElement.className = 'class2';

        innerElement.className = 'class1';

        addListener(outerElement, 'click', outerFunc);//클릭시 outerFunc

        addListener(innerElement, 'click', innerFunc);//클릭시 innerFunc 수행해라

      }

      

      // 크로스 브라우징을 고려해 구현한 이벤트 리스너 등록  함수입니다.

      // el : 이벤트가 발생할 HTML 요소

      // ev : 이벤트

      // handler : 이벤트 핸들러 함수

      function addListener(el, ev, handler) {

        // FireFox, Chrome 같은 IE 웹브라우저의 경우

        if (el.addEventListener) {

          el.addEventListener(ev, handler, false)

        } else { // IE 브라우저의 경우

          el.attachEvent('on' + ev, handler);

        }

      }

      

      addListener(window, 'load', init);

      

    </script>

  </head>

  <body>

    <div id="outer">

      외부영역을

      <div id="inner">

        내부 영역을 클릭해 보세요!!!

      </div>

      클릭해보세요!!!

    </div>

    <div id="result">

    </div>

  </body>

</html>


출력 화면


버블링을 억제 했을 때.


버블링을 억제하지 않았을 때



무조건 outer에서 클릭이벤트가 발생했다고 뜬다. 이유는 result 영역을 같이써서 이벤트 버블링에 의해서 이렇게 뜬다.


이벤트 버블링 보충 설명


출처 : http://egloos.zum.com/namelessja/v/4022528


1. DOM Event란?

HTML문서나 브라우저 창에서 특정 순간에 일어난 일을 가리킨다.

이벤트는 IE3과 Netscape2일 때, 폼 처리 시 브라우저와 서버 사이의 데이터 교환을 줄이려는 목적에서 도입되었다.

후에 IE4와 Netscape4에서부터 각기 다른 API를 사용하면서 이벤트 처리가 달라지기 시작했다.

그리고, IE9, FF, Chrome에서는 이를 표준화시키기 위하여 DOM레벨 2의 이벤트를 구현하였다.

이러한 과정을 거치면서, 전용 이벤트 API를 보유한 브라우저는 IE8이 마지막이다.


2. 이벤트 흐름

DOM에서 이벤트를 전달하는 순서는 2가지가 있다.

IE에서는 이벤트 버블링을 지원했고, Netscape에서는 이벤트 캡쳐링을 지원했다.

먼저 다음과 같은 예제에서 발생되는 이벤트 흐름을 보자

<html>

        <head>

        <title>Event Bubbling Example</title>

        </head>

        <body>

        <div id=”myDiv”>Click Me</div>

        </body>

</html>



2-1. 버블링

버블링은 가장 깊은 엘리먼트에서 점점 부모 엘리먼트로 따라 올라가면서 발생하는 이벤트이다.

이는 다음과 같은 순서대로 이벤트가 발생한다.

1. div

2.body

3.html

4.document

5.Window(IE9,FF,Chrome에서만)



2-2. 캡쳐링

캡쳐링은 버블링과는 반대로 최상위 엘리먼트에서 최하위 엘리먼트로 따라내려가는 방법이다,.

1. Window (IE9, FF, Chrome만)

2.document

3.html

4.body

5.div



2-3. DOM2의 이벤트 흐름

DOM2에서는 이벤트 캡쳐링 -> 타겟 -> 이벤트 버블링을 거친다.

하지만, IE9, FF, Chrome에서는 이벤트 캡쳐링 단계에서 타겟으로 이벤트를 넘기므로,

결과적으로 이벤트 작업의 기회가 2번 생긴다.



7.       웹브라우저별 이벤트 핸들링 모델



8.       웹브라우저 호환성 테스트 정리


IE8이하는 addEventLister가 적용 안됨.






반응형