로그인

이메일
비밀번호
왼쪽에 걸리적 거리는 거 숨기기

'이벤트'에 해당되는 글 3건

  1. 브라우저별 이벤트 정리 (2)

    2008/05/16
  2. 이벤트 객체의 보관 (5)

    2008/03/12
  3. FF 에서 한글 입력시에 onKeyUp 이벤트 잡기 흉내 (7)

    2007/11/08

주옥과 같은 자료
http://www.quirksmode.org/dom/events/index.html

존재조차 몰랐던 이벤트도 많이 있구나.
영양가 있는 포스팅인가요
(총 1분이 투표해서 2.0점) 2.0점
2008/05/16 22:15 2008/05/16 22:15

IE 의 경우 이벤트 객체는 매번 이벤트가 생길때마다 window.event 변수에 할당되기 때문에 window.event 에 해당하는 값이 지속될 것이라고 기대할 수가 없습니다.

아래 코드를 보세요.

(Language : html4strict)
  1.     <script type="text/javascript" language="javascript">
  2.  
  3.       function onClick(e) {
  4.         showSourceTag(e);
  5.       }
  6.  
  7.       function showSourceTag(e) {
  8.  
  9.         var srcElement = e.target || e.srcElement;
  10.         alert(srcElement.tagName);
  11.  
  12.       }
  13.  
  14.     </script>
  15.   </head>
  16.     <button onclick="onClick(event);">CLICK ME</button>
  17.   </body>
  18. </html>

위의 코드는 버튼을 클릭했을때 이벤트가 발생한 엘리먼트의 태그이름을 보여주는 코드입니다. <button> 태그를 클릭했을때 핸들러가 호출되니 물론 결과는 BUTTON 이라고 나오겠죠.

하지만 onClick 함수를 아래 처럼 바꾸면 문제가 생깁니다.

(Language : javascript)
  1. function onClick(e) {
  2.  
  3.   setTimeout(function() {
  4.     showSourceTag(e);
  5.   }, 100);
  6. }

얻은 이벤트 참조를 0.1초후에 사용하게 되기 때문에 showSource 안에서 에러가 나게 되죠.
이 문제의 해결을 위해서는 createEventObject 함수를 이용해 이벤트 객체를 일단 복사해 놓고 사용하도록 해야 합니다, 아래처럼요.

(Language : javascript)
  1. function onClick(e) {
  2.  
  3.   var clone = document.createEventObject ? document.createEventObject(e) : e;
  4.  
  5.   setTimeout(function() {
  6.     showSourceTag(clone);
  7.   }, 100);
  8. }

이벤트 객체를 보관해서 써야 할 때는 createEventObject 함수로 복사해 놓고 쓰세요~
개발을 하다가 아래 같은 생소한 에러메시지를 접하고 삽질하다가 해당 문제임을 알았네요;

사용자 삽입 이미지

끝.
영양가 있는 포스팅인가요
(총 2분이 투표해서 4.5점) 4.5점
2008/03/12 15:54 2008/03/12 15:54

Windows 에서는 (Mac, Linux 등 딴 건 몰겠다. 테스트 하기 귀찮아-_-)
IE 외의 다른 브라우저 (FF, Opera) 에서 한글을 입력하는 중에는 onKeyUp, onKeyDown, onKeyPress 이벤트가 모두 발생하지 않는다.

따라서 자동완성 같이 한글이 입력되는 과정을 트래킹해야 하는 경우 난감해지는데...

그래서 그 동안 비 IE 에서는 Interval 타이머를 돌려서 텍스트필드의 값을 주기적으로 체크해 변화가 생기면 반영시키는 식으로 만들었었고,

이번에도 그렇게 만들고 있다가, 문득 뭔가 방법이 없을까 해서 인터넷을 뒤져봤지만
다른 사람들도 다들 그렇게 쓰고 있는 듯 했다-_-;

그러다가 onFocus 일때 타이머 만들고 onBlur 일때 타이머 죽이고,
타이머에서는 값 바뀌는지 체크하고, 뭐 이런 코드 작성할 필요 없이 편리하게 한방에 사용할 수 있는 클래스를 만들어 봤다.

비 IE 에서도 한글을 입력하는 도중에 onKeyUp 이벤트가 발생하도록 해주는 코드이다.

구현 방법은 타이머를 돌려서 텍스트필드 값이 변화가 발생하면 createEvent 로 keyUp 이벤트를 생성해서 억지로(?) 발생시키게 했다.

onKeyDown, onKeyPress, onKeyUp 중에서 onKeyUp 만 지금 막 입력한 값이 반영된 이후에 발생하는 이벤트라서 onKeyUp 를 흉내내기로 했다.

observe.js (Language : javascript)
  1. /**
  2. * 폼엘리먼트의 value 가 변화되면 keyup 이벤트 발생시키기
  3. *
  4. * @author hooriza at nhncorp.com
  5. * @version 0.1
  6. *
  7. * @created Nov.8.2007.
  8. */
  9.  
  10. var Observe = function(oEl) {
  11.  
  12.   this._o = oEl;
  13.   this._value = oEl.value;
  14.  
  15.   this._bindEvents();
  16.  
  17. };
  18.  
  19. Observe.prototype._bindEvents = function() {
  20.  
  21.   var self = this;
  22.   var bind = function(oEl, sEvent, pHandler) {
  23.     if (oEl.attachEvent) oEl.attachEvent('on' + sEvent, pHandler);
  24.     else oEl.addEventListener(sEvent, pHandler, false);
  25.   };
  26.  
  27.   bind(this._o, 'focus', function() {
  28.    
  29.     if (self._timer) clearInterval(self._timer);
  30.     self._timer = setInterval(function() {
  31.      
  32.       // window.console.debug('compare : ' + self._value + ' == ' + self._o.value);
  33.       if (self._value != self._o.value) {
  34.         self._value = self._o.value;
  35.         self._fireEvent();
  36.       }
  37.      
  38.     }, 50);
  39.    
  40.   });
  41.  
  42.   bind(this._o, 'blur', function() {
  43.    
  44.     if (self._timer) clearInterval(self._timer);
  45.     self._timer = null;
  46.    
  47.   });
  48.            
  49. };
  50.  
  51. Observe.prototype._fireEvent = function() {
  52.          
  53.   if (document.createEvent) {
  54.    
  55.     var e;
  56.    
  57.     if (window.KeyEvent) {
  58.      
  59.       e = document.createEvent('KeyEvents');
  60.       e.initKeyEvent('keyup', true, true, window, false, false, false, false, 65, 0);
  61.      
  62.     } else {
  63.      
  64.       e = document.createEvent('UIEvents');
  65.       e.initUIEvent('keyup', true, true, window, 1);
  66.       e.keyCode = 65;
  67.      
  68.     }
  69.    
  70.     this._o.dispatchEvent(e);
  71.    
  72.   } else {
  73.    
  74.     var e = document.createEventObject();
  75.     e.keyCode = 65;
  76.    
  77.     this._o.fireEvent('onkeyup', e);
  78.    
  79.   }
  80.  
  81. };

한가지 문제는 onKeyUp 이벤트가 빈번히 발생한다는 거...
뭐 이건 onKeyUp 핸들러에서 텍스트필드 값이 안 바뀌었으면 무시하도록 하면 된다.

아래는 사용 예.

sample.html (Language : html4strict)
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2. <html lang="ko">
  3.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  4.     <title>AutoHide</title>
  5.     <script type="text/javascript" src="observe.js"></script>
  6.     <script type="text/javascript">
  7.      
  8.       window.onload = function() {
  9.         new Observe(document.getElementById('FOO'));
  10.       };
  11.      
  12.       function onKeyUp(sValue) {
  13.         document.getElementById('debug').innerHTML += sValue + '<br>';
  14.       }
  15.      
  16.     </script>
  17.   </head>
  18.     <span id="TIMER">TIMER</span>
  19.     <input type="text" id="FOO" onkeyup="onKeyUp(this.value);" />
  20.     <div id="debug"></div>
  21.   </body>
  22. </html>


영양가 있는 포스팅인가요
(총 2분이 투표해서 4.0점) 4.0점
2007/11/08 20:37 2007/11/08 20:37