mozilla
검색 결과

    More Event Handlers

     

    이번 단원에서는 이벤트 객체에 대해 검토해보고, 추가적인 이벤트들에 대해 설명하겠습니다.

    이벤트 객체

    각 이벤트 핸들러는 event 객체가 저장된 하나의 인자를 가집니다. 속성 형식의 이벤트 리스너에서의 이벤트 객체는 명시하지 않더라도 스크립트 코드에서 'event'라는 이름으로 참조할 수 있습니다. addEventListener 형태일 경우에는 리스너 함수의 첫 번째 인자가 이벤트 객체가 됩니다. 이벤트 객체에는 이벤트가 처리되는 동안 사용할 수 있는 많은 속성이 있습니다. 전체 목록은 XULPlanet object reference에서 보실 수 있습니다.

    우리는 지난 단원에서 이벤트의 target 속성에 대해 알아 보았습니다. 이 속성은 이벤트가 발생한 대상 요소에 대한 참조를 가지고 있습니다. 이와 유사한 currentTarget 속성은 현재 이벤트 리스너가 처리하고 있는 대상 요소에 대한 참조를 가집니다. 아래 예제에서 target 속성은 활성화된 버튼이나 체크박스 중 하나에 대한 참조인 반면 currentTarget 속성은 항상 vbox가 됩니다.

    예제 1 : Source View

    <vbox oncommand="alert(event.currentTarget.tagName);">
      <button label="OK"/>
      <checkbox label="Show images"/>
    </vbox>
    

    이벤트 전파 중지

    일단 이벤트를 처리하였으면, 이벤트의 전파 단계 중 어디에 있는지에 상관없이, 이벤트의 버블링이나 캡처 단계를 중지하여 다른 요소들로 이벤트가 전파되는 것을 막고자 할때가 있을 것입니다. 이는 이벤트 핸들러를 대상 요소에 어떻게 부착했는지에 따라 그 방법이 달라집니다.

    캡처 단계는 버블링 단계 이전에 발생한다고 했던 것을 기억하세요. 그렇게 때문에 캡처 단계에서 실행되는 리스너는 버블 단계의 리스너보다 먼저 실행됩니다. 만일 캡처 단계에서 이벤트 전파가 중지된다면, 이후에 발생할 수 있는 캡처 리스너나 버블링 리스너는 해당 이벤트에 대해 아무런 알림도 받지 못하게 됩니다. 이벤트 전파를 막기 위해서는 다음 예제와 같이 이벤트 객체의 stopPropagation 메소드를 호출하면 됩니다.

    예제 2 : Source View

    <hbox id="outerbox">
      <button id="okbutton" label="OK"/>
    </hbox>
    
    <script>
    function buttonPressed(event){
      alert('Button was pressed!');
    }
    
    function boxPressed(event){
      alert('Box was pressed!');
      event.stopPropagation();
    }
    
    var button = document.getElementById("okbutton");
    button.addEventListener('command',buttonPressed,true);
    
    var outerbox = document.getElementById("outerbox");
    outerbox.addEventListener('command',boxPressed,true);
    </script>
    

    예제에서, 한 이벤트 리스너는 버튼에 또 다른 이벤트 리스너는 상자에 추가되었습니다. stopPropagation 메소드는 상자의 리스너에서 호출되므로, 버튼의 리스너는 절대 호출되지 않습니다. 만일 이 메소드가 제거되면 모든 리스너가 호출되고 2개의 알림창(alert)이 나타날 것입니다.

    기본 행위 막기

    어떤 요소에 아무런 이벤트 핸들러도 등록되어 있지 않다면, 캡처와 버블링 단계가 다 끝난후에 내장된(default) 방법으로 이벤트가 처리됩니다. 이 내장된 방법은 이벤트와 대상 요소의 종류에 따라 다릅니다. 예를 들어 'popupshowing' 이벤트는 팝업이 출력되기 전에 전달받는 이벤트이며, 기본(default) 동작은 팝업을 출력하는 것입니다. 만일 기본 동작이 일어나지 않도록 하면, 팝업은 출력되지 않을 것입니다. 기본 동작은 이벤트 객체의 preventDefault 메소드로 막을 수 있으며, 아래의 예제와 같습니다.

    예제 3 : Source View

    <button label="Types" type="menu">
      <menupopup onpopupshowing="event.preventDefault();">
        <menuitem label="Glass"/>
        <menuitem label="Plastic"/>
      </menupopup>
    </button>
    

    속성 형태로 작성된 이벤트 리스너에서는 해당 코드에서 false값을 반환하도록 해서 기본 행위를 막을 수 있는 방법도 있습니다. 기본 동작을 막는 것은 stopPropagation 메소드로 이벤트 전파를 막는 것과는 다르다는 사실을 알아두세요. 기본 행위가 막혀 있더라도, 이벤트는 계속 진행됩니다. 마찬가지로, stopPropagation 메소드를 호출한다고 해서 기본 동작이 실행되지 않는 것은 아닙니다. 여러분은 두 동작을 모두 실행되지 않게 하기 위해서는 두 메소드 모두 호출해야 합니다.

    일단 이벤트 전파나 기본 동작을 막았다면 다음 이벤트에서도 동일하게 동작할 것입니다.

    다음 단원의 내용은 자주 사용되는 몇가지 이벤트 목록입니다. 전체 목록은 XULPlanet event reference를 참조하세요.

    마우스 이벤트

    마우스만의 동작을 처리하는데 사용되는 여러가지 이벤트가 있으며, 간략한 설명은 아래와 같습니다.

    click 
    마우스로 대상 요소를 클릭했을때(버튼을 눌렀다 땔때) 호출됩니다.
    dblclick 
    마우스 버튼을 더블클릭했을때 호출됩니다.
    mousedown 
    마우스 버튼이 대상 요소에 눌러졌을때 호출됩니다. 이벤트 핸들러는 마우스 버튼이 눌러지면 떨어지지 않더라도 호출됩니다.
    mouseup 
    마우스 버튼이 떨어질때 호출됩니다.
    mouseover 
    마우스 포인터가 요소위로 움직이면 호출됩니다. 이 이벤트는 요소를 강조(highlight)하기 위해서 사용할 수 있지만, CSS에서 이런 것을 자동으로 처리하므로 이벤트로 처리할 필요는 없습니다. 그래도 상태바에 몇 가지 도움말을 제공하고자 할 때 사용할 수 있습니다.
    mousemove 
    마우스 포인터가 요소 위에서 움직이면 호출됩니다. 이 이벤트는 마우스를 움직임에 따라 자주 호출될 수 있기 때문에 긴 시간이 걸리는 작업을 이 핸들러에서 수행하도록 하는 것은 바람직하지 않습니다.
    mouseout 
    마우스 포인터가 대상 요소의 밖으로 나갈 때 호출됩니다. 강조된 대상 요소를 원래데로 바꾸거나 상태바의 텍스트를 제거할 때 사용할 수 있습니다.

    이것들 외에도 드래그와 관련된 이벤트들이 있으며 이는 사용자가 마우스 버튼을 누른 상태에서 주위로 끌 때 발생합니다. 이러한 이벤트들에 대해서는 Drag and Drop에서 설명하겠습니다.

    마우스 버튼 이벤트 속성

    마우스 버튼 이벤트가 발생하면, 어떤 마우스 버튼이 눌러졌는지와 마우스 포인터의 위치가 어디인지를 확인할 수 있는 속성을 사용할 수 있습니다. 이벤트의 button 속성은 어떤 버튼이 눌러졌는지를 나타내는 속성으로, 왼쪽 버튼은 0, 오른쪽 버튼은 1, 가운데 버튼은 2의 값을 가집니다. 마우스의 버튼이 다르게 설정되었다면 값이 달라질 수 있습니다.

    detail 속성은 버튼이 빠른 시간 내 순차적으로 클릭된 횟수를 저장합니다. 이 속성을 이용해서 한번 클릭인지, 더블 클릭인지 혹은 3회 클릭인지를 확인할 수 있습니다. 물론 더블 클릭만 확인하고자 하면 dblclick 이벤트를 사용할 수 있습니다. click 이벤트가 첫 번째 클릭에 의해 발생하고 두번째 클릭, 세번째 클릭 각각에 대해 이벤트가 발생하지만 dblclick 이벤트는 더블 클릭시 한번만 발생합니다.

    buttondetail 속성은 마우스 버튼과 관련된 이벤트에만 해당됩니다. 마우스의 움직임과 관련된 이벤트에서는 해당 속성값이 0으로 설정될 것입니다.

    마우스 위치 관련 이벤트 속성

    그러나 모든 마우스 이벤트에는 이벤트가 발생한 마우스 위치 좌표를 저장하는 속성이 있습니다. 이 속성에는 두 가지 종류의 좌표가 있습니다. 첫 번째는 screenXscreenY 속성으로 화면의 좌상단에 상대적인 좌표입니다. 두 번째는 clientXclientY로 문서의 좌상단에 상대적인 좌표입니다. 다음은 현재의 마우스 좌표를 출력하는 예제입니다.

    예제 4 : Source View

    <script>
    
    function updateMouseCoordinates(event){
      var text = "X:" + event.clientX + " Y:" + event.clientY;
      document.getElementById("xy").value = text;
    }
    </script>
    
    <label id="xy"/>
    <hbox width="400" height="400" onmousemove="updateMouseCoordinates(event);"/>
    

    예제에서는 상자의 크기를 명시적으로 지정했기 때문에 효과를 좀더 쉽게 볼 수 있습니다. 이벤트 핸들러는 clientXclientY 속성값을 얻어 문자열을 만들었습니다. 그리고 이 문자열을 라벨의 value 속성에 할당했습니다. updateMouseCoordinates 함수의 인자로 event가 넘어오는 것을 기억하세요. 만일 상자의 경계을 넘어 빠르게 마우스가 이동한다면, 아마 마우스 좌표가 400에 정확히 멈추지 않는 것을 알게 될것입니다. 이것은 mousemove 이벤트가 일정한 간격으로 발생하며, 다음 이벤트가 발생하기 전에 마우스의 위치가 밖으로 빠져나갔기 때문입니다. 당연히 마우스가 움직이는 매 픽셀마다 mousemove 이벤트가 전송된다면 너무 비효율적일 것입니다.

    요소에 상대적인 좌표

    여러분은 전체 창이 아닌 이벤트가 발생한 요소에 상대적인 좌표(요소 내에서의 좌표)를 얻고자 할때가 있을 것입니다. 이는 이벤트의 위치에서 요소의 위치를 빼주면 얻을 수 있으며 코드는 다음과 같습니다.

    var element = event.target;
    var elementX = event.clientX - element.boxObject.x;
    var elementY = event.clientY - element.boxObject.y;
    

    XUL 요소들에는 boxObject라는 속성을 사용해서 얻을 수 있는 상자 객체가 있습니다. 상자 객체에 대해서는 이후 단원에서 배우겠지만, 간단히 말해서 이 객체는 요소가 출력되는 방법에 대한 정보(요소의 x, y 좌표등)를 가지고 있다고 보면 됩니다. 예제 코드에서는 요소 기준의 이벤트 좌표를 얻기 위해 이벤트 좌표에서 상자 객체의 좌표를 뺐습니다.

    로드(load) 이벤트

    로드 이벤트는 XUL 파일의 로딩이 완료되고 내용이 출력되기 직전에 문서(window 태그)로 전송됩니다. 이 이벤트는 일반적으로 변수들을 초기화하고 사용자가 창을 사용할 수 있기 전에 해야 할 일들을 처리하는데 사용됩니다. 여러분은 이러한 초기화 작업을 함수 외부의 최상위 레벨 스크립트로 처리하는 것보다는 로드 이벤트를 사용하는 것이 좋습니다. 이것은 XUL 요소들이 로드되지 않았거나 초기화되지 않았을수도 있기 때문이며, 따라서 어떤 것들은 원하는데로 동작하지 않을 수 있습니다. 로드 이벤트를 사용하려면 window 태그에 onload 속성을 넣으면 됩니다. 초기화를 필요로 하는 것들은 로드 이벤트 핸들러에서 호출하세요.

    또한 창이 닫힐 때 혹은 브라우저의 관점에서는 페이지가 다른 URL로 넘어갈 때 발생하는 언로드(unload) 이벤트가 있습니다. 이 이벤트는 창이 닫히기 전 변경된 정보를 저장하는 것과 같은 용도로 사용할 수 있습니다.

    다음에는 단축키를 추가하는 방법에 대해 알아보겠습니다.

    문서 태그 및 공헌자

    태그: 
    Contributors to this page: teoli, iruis, Suguni
    최종 변경: iruis,