comet

Development/JavaScript 2012. 12. 28. 14:29


Comet is a web application model in which a long-held HTTP request allows a web server to push data to a browser, without the browser explicitly requesting it.[1][2] Comet is an umbrella term, encompassing multiple techniques for achieving this interaction. All these methods rely on features included by default in browsers, such as JavaScript, rather than on non-default plugins. The Comet approach differs from the original model of the web, in which a browser requests a complete web page at a time.[3]

The use of Comet techniques in web development predates the use of the word Comet as a neologism for the collective techniques. Comet is known by several other names, including Ajax Push,[4][5] Reverse Ajax,[6] Two-way-web,[7]HTTP Streaming,[7] and HTTP server push[8] among others.[9]

Contents

  [hide

[edit]Implementations

Comet applications attempt to eliminate the limitations of the page-by-page web model and traditional polling by offering real-time interaction, using a persistent or long-lasting HTTP connection between the server and the client. Since browsers and proxies are not designed with server events in mind, several techniques to achieve this have been developed, each with different benefits and drawbacks. The biggest hurdle is the HTTP 1.1 specification, which states that a browser should not have more than two simultaneous connections with a web server.[10] Therefore, holding one connection open for real-time events has a negative impact on browser usability: the browser may be blocked from sending a new request while waiting for the results of a previous request, e.g., a series of images. This can be worked around by creating a distinct hostname for real-time information, which is an alias for the same physical server.

Specific methods of implementing Comet fall into two major categories: streaming and long polling.

[edit]Streaming

An application using streaming Comet opens a single persistent connection from the client browser to the server for all Comet events. These events are incrementally handled and interpreted on the client side every time the server sends a new event, with neither side closing the connection.[3]

Specific techniques for accomplishing streaming Comet include the following:

[edit]Hidden iframe

A basic technique for dynamic web application is to use a hidden iframe HTML element (an inline frame, which allows a website to embed one HTML document inside another). This invisible iframe is sent as a chunked block, which implicitly declares it as infinitely long (sometimes called "forever frame"). As events occur, the iframe is gradually filled with script tags, containing JavaScript to be executed in the browser. Because browsers render HTML pages incrementally, each script tag is executed as it is received.[11]

One benefit of the iframe method is that it works in every common browser. Two downsides of this technique are the lack of a reliable error handling method, and the impossibility of tracking the state of the request calling process.[11]

[edit]XMLHttpRequest

The XMLHttpRequest (XHR) object, the main tool used by Ajax applications for browser–server communication, can also be pressed into service for server–browser Comet messaging, in a few different ways.

In 1995, Netscape Navigator added a feature called “server push”, which allowed servers to send new versions of an image or HTML page to that browser, as part of a multipart HTTP response (see History section, below), using the content type multipart/x-mixed-replace. Since 2004, Gecko-based browsers such as Firefox accept multipart responses to XHR, which can therefore be used as a streaming Comet transport.[12] On the server side, each message is encoded as a separate portion of the multipart response, and on the client, the callback function provided to the XHR onreadystatechange function will be called as each message arrives. This functionality is only included in Gecko-based browsers, though there is discussion of adding it to WebKit.[13] Internet Explorer 10 now also support this functionality.[14]

Instead of creating a multipart response, and depending on the browser to transparently parse each event, it is also possible to generate a custom data format for an XHR response, and parse out each event using browser-side JavaScript, relying only on the browser firing the onreadystatechange callback each time it receives new data.

[edit]Ajax with long polling

None of the above streaming transports work across all modern browsers without negative side-effects. This forces Comet developers to implement several complex streaming transports, switching between them depending on the browser. Consequently many Comet applications use long polling, which is easier to implement on the browser side, and works, at minimum, in every browser that supports XHR. As the name suggests, long polling requires the client to poll the server for an event (or set of events). The browser makes an Ajax-style request to the server, which is kept open until the server has new data to send to the browser, which is sent to the browser in a complete response. The browser initiates a new long polling request in order to obtain subsequent events. Specific technologies for accomplishing long-polling include the following:

[edit]XMLHttpRequest long polling

For the most part, XMLHttpRequest long polling works like any standard use of XHR. The browser makes an asynchronous request of the server, which may wait for data to be available before responding. The response can contain encoded data (typically XML or JSON) or Javascript to be executed by the client. At the end of the processing of the response, the browser creates and sends another XHR, to await the next event. Thus the browser always keeps a request outstanding with the server, to be answered as each event occurs.

[edit]Script tag long polling

While any Comet transport can be made to work across subdomains, none of the above transports can be used across different second-level domains (SLDs), due to browser security policies designed to prevent cross-site scriptingattacks.[15] That is, if the main web page is served from one SLD, and the Comet server is located at another SLD, Comet events cannot be used to modify the HTML and DOM of the main page, using those transports. This problem can be sidestepped by creating a proxy server in front of one or both sources, making them appear to originate from the same domain. However, this is often undesirable for complexity or performance reasons.

Unlike iframes or XMLHttpRequest objects, script tags can be pointed at any URI, and JavaScript code in the response will be executed in the current HTML document. This creates a potential security risk for both servers involved, though the risk to the data provider (in our case, the Comet server) can be avoided using JSONP.

A long-polling Comet transport can be created by dynamically creating script elements, and setting their source to the location of the Comet server, which then sends back JavaScript (or JSONP) with some event as its payload. Each time the script request is completed, the browser opens a new one, just as in the XHR long polling case. This method has the advantage of being cross-browser while still allowing cross-domain implementations.[15]

[edit]History

[edit]Early Java applets

The ability to embed Java applets into browsers (starting with Netscape 2.0 in March 1996[16]) made real-time communications possible, using a raw TCP socket[17] to communicate between the browser and the server. This socket can remain open as long as the browser is at the document hosting the applet. Event notifications can be sent in any format — text or binary — and decoded by the applet.

[edit]First Comet applications

In March 2006, software engineer Alex Russell coined the term Comet in a post on his personal blog.[18] The new term was a play on Ajax (Ajax and Comet both being household cleaners common in the USA).[19][20][21]

Even if not yet known by that name, the very first Comet implementations date back to 2000,[22] with the PushletsLightstreamer, and KnowNow projects. In 2006, some applications exposed those techniques to a wider audience:Meebo’s multi-protocol web-based chat application enables users to connect to AOLYahoo, and Microsoft chat platforms through the browser; Google added web-based chat to GmailJotSpot, a startup since acquired by Google, built Comet-based real-time collaborative document editing.[23] New Comet companies and enterprise solutions were created, such as the Java-based ICEfaces JSF framework (although they prefer the term "Ajax Push"[5]). Others that had previously used Java-applet based transports switched instead to pure-JavaScript implementations.[24]

[edit]Alternatives

Browser-native technologies are inherent in the term Comet. Attempts to improve non-polling HTTP communication have come from multiple sides:

  • The HTML 5 draft specification produced by the Web Hypertext Application Technology Working Group (WHATWG) specifies so called server-sent events,[25] which defines a new Javascript interface EventSource and a new MIME type text/event-stream. Experimental implementation of this feature was introduced in Opera 9.[26]
  • The HTML 5 WebSocket API working draft specifies a method for creating a persistent connection with a server and receiving messages via an onmessage callback.[27]
  • The Bayeux protocol by the Dojo Foundation. It leaves browser-specific transports in place, and defines a higher-level protocol for communication between browser and server, with the aim of allowing re-use of client-side JavaScript code with multiple Comet servers, and allowing the same Comet server to communicate with multiple client-side JavaScript implementations. Bayeux is based on a publish/subscribe model, so servers supporting Bayeux have publish/subscribe built-in.[28]
  • The BOSH protocol by the XMPP standards foundation. It emulates a bidirectional stream between browser and server by using two synchronous HTTP connections.
  • The JSONRequest object, proposed by Douglas Crockford, would be an alternative to the XHR object.[29]
  • Use of plugins, such as Java applets or the proprietary Adobe Flash (using RTMP protocol for data streaming to Flash applications). These have the advantage of working identically across all browsers with the appropriate plugin installed and need not rely on HTTP connections, but the disadvantage of requiring the plugin to be installed
  • Google announced[30] a new Channel API for Google App Engine,[31] implementing a Comet-like API with the help of a client Javascript library on the browser. It could be later replaced by HTML5 WebSocket, however.

[edit]See also

[edit]References

  1. ^ Krill, Paul (September 24, 2007). "AJAX alliance recognizes mashups"InfoWorld. Retrieved 2010-10-20.
  2. ^ Crane, Dave; McCarthy, Phil (October 13, 2008). Comet and Reverse Ajax: The Next-Generation Ajax 2.0Apress.ISBN 978-1-59059-998-3.
  3. a b Gravelle, Rob. "Comet Programming: Using Ajax to Simulate Server Push"Webreference.com. Retrieved 2010-10-20.
  4. ^ Egloff, Andreas (2007-05-05). Ajax Push (a.k.a. Comet) with Java Business Integration (JBI) (Speech). JavaOne 2007,San Francisco, CaliforniaSun Microsystems, Inc.. Retrieved 2008-06-10.
  5. a b "Ajax Push". ICEfaces.org. Retrieved 2008-07-21.
  6. ^ Crane, Dave; McCarthy, Phil (July 2008). Comet and Reverse Ajax: The Next Generation Ajax 2.0. Apress. ISBN 1-59059-998-5.
  7. a b Mahemoff, Michael (June 2006). "Web Remoting". Ajax Design PatternsO'Reilly Media. pp. 19; 85. ISBN 0-596-10180-5.
  8. ^ Double, Chris (2005-11-05). "More on Ajax and server push"Different ways of doing server push. Retrieved 2008-05-05.
  9. ^ Nesbitt, Bryce (2005-11-01). "The Slow Load Technique/Reverse AJAX"Simulating Server Push in a Standard Web Browser. Retrieved 2008-05-05.
  10. ^ HTTP 1.1 specification, section 8.1.4. W3C. Retrieved 30 November 2007
  11. a b Holdener III, Anthony T. (January 2008). "Page Layout with Frames that Aren't". Ajax: The Definitive GuideO'Reilly Media. p. 320. ISBN 0-596-52838-8.
  12. ^ Johnny Stenback, et al. (March–April 2004). “Bug 237319 – Add support for server push using multipart/x-mixed-replacewith XMLHttpRequest”. Mozilla bug tracking. Retrieved 29 November 2007. Also see:
    Alex Russell (6 August 2005). “Toward server-sent data w/o iframes”. Alex Russell’s blog. Retrieved 29 November 2007.
  13. ^ Rob Butler, et al. (June 2006). “Bug 14392: Add support for multipart/x-mixed-replace to XMLHttpRequest”. Webkit bug tracking. Retrieved 29 November 2007.
  14. ^ http://msdn.microsoft.com/en-us/library/ie/hh673569%28v=vs.85%29.aspx
  15. a b Flanagan, David (2006-08-17). "13.8.4 Cross-Site Scripting". JavaScript the Definitive Guide. The Definitive Guide.O'Reilly Media. p. 994. ISBN 0-596-10199-6.
  16. ^http://web.archive.org/web/19961115203505/www27.netscape.com/comprod/products/navigator/version_2.0/index.htmlNetscape.com from 1996 (via Archive.org)
  17. ^ http://java.sun.com/j2se/1.4.2/docs/api/java/net/Socket.html
  18. ^ Alex Russell (3 March 2006). “Comet: Low Latency Data for the Browser”. Alex Russell’s blog. Retrieved 29 November 2007.
  19. ^ K. Taft, Darryl (2006-05-12). "Microsoft Scrubs Comet from AJAX Tool Set". eWEEK.com. Retrieved 2008-07-21.
  20. ^ Orbited: Enabling Comet for the Masses: OSCON 2008 - O'Reilly Conferences, July 21 - 25, 2008, Portland, Oregon
  21. ^ Enterprise Comet & Web 2.0 Live Presentation
  22. ^ "CometDaily: Comet and Push Technology".
  23. ^ Dion Almaer (29 September 2005). “Jotspot Live: Live, group note-taking” (interview with Abe Fettig). Ajaxian. Retrieved 15 December 2007.
    Matt Marshall (15 December 2006). “Renkoo launches event service — in time to schedule holiday cocktails”. Venture Beat. Retrieved 15 December 2007.
  24. ^ Clint Boulton (27 December 2005). “Startups Board the AJAX Bandwagon”. DevX News. Retrieved 18 February 2008.
  25. ^ Ian Hickson, ed. (2007-10-27). "6.2 Server-sent DOM events"HTML 5 - Call For CommentsWHATWG. Retrieved 2008-10-07.
  26. ^ Bersvendsen, Arve (2006-09-01). "Event Streaming to Web Browsers"Opera Software. Retrieved 2009-06-01.
  27. ^ Hickson, Ian (2009-04-23). "The WebSocket API"w3c. Retrieved 2009-07-21.
  28. ^ Alex Russell, et al. (2007). "Bayeux Protocol - Bayeux 1.0draft1.". Dojo Foundation. Retrieved 2007-12-14.
  29. ^ Crockford, Douglas (2006-04-17). "JSONRequest Duplex"An alternative to XMLHttpRequest for long lasting server initiated push of data. Retrieved 2008-05-05.
  30. ^ http://googleappengine.blogspot.com/2010/12/happy-holidays-from-app-engine-team-140.html
  31. ^ http://arstechnica.com/web/news/2010/12/app-engine-gets-streaming-api-and-longer-background-tasks.ars



Comet (혜성)는 Web 어플리케이션 을 구축 할 때 사용되는 기술로,이 기술을 사용하면 서버 에서 발생한 이벤트 를 클라이언트 의 요청없이 클라이언트 에 보낼 수있다.

Comet은 이러한 통신을 실현하기위한 여러 기법을 정리 한 개념이다. 이러한 기술은 브라우저에 플러그인을 추가하지 않고 ( JavaScript 와 같은) 기본 기능으로 실현되는 것이다. 이론적으로는 Comet은 브라우저가 데이터를 요구하는 형태의 기존 웹 모델과는 다르다. 실제로 Comet 애플리케이션은 Ajax 와 Long polling 을 사용하여 서버에 새 데이터를 검색한다.

목차

  [ 숨기기 ] 

왜 필요한가 편집 ]

기존의 방법으로는 웹 페이지는 클라이언트에서 요청이있을 때 만 클라이언트에 전달되고 있었다. 클라이언트가 요청할 때마다 브라우저는 서버에 HTTP 연결을 생성하고 웹 서버는 클라이언트에 데이터를 반환하고 연결이 닫힙니다. 이 방법의 단점은 사용자가 명시 적으로 페이지를 새로 실시하거나 사용자가 새로운 페이지로 이동하는 경우에만 표시되는 페이지가 갱신되지 않는 것이다. 페이지를 전송하는 데 긴 시간을 요하기 때문에, 페이지를 새로 엄청난 지연을 만들어 낸다.

이 문제를 해결하기 위해, 브라우저에 변경된 부분 만 요청 업데이트시키는 기술이다 Ajax 를 사용할 수있다. 이 방법은 데이터 트래픽이 기존의 방법보다 줄어들 기 때문에 지연의 정도도 줄어 전체 사이트의 성능 향상이라고 할 수있다. 다시 말하면, 비동기 통신을 이용함으로써 사용자는 단계적으로 데이터를 수신하면서 작업을 할 수 있기 때문에, 그런 의미에서도 성능이 향상된다.

그러나 Ajax를 사용하더라도 클라이언트가 데이터를 검색하기 전에 이에 대한 요청을 내야한다는 어려운 문제는 여전히 존재한다. 이 문제는, 예를 들면 "있는 사용자가 데이터를 보내왔다"라고하는 서버에서 이벤트가 발생할 때까지 대기해야하는 응용 프로그램을 설계 할 때 큰 장애가된다.

서버에서 이벤트가 발생했는지 여부를 정기적으로 확인한다 (이른바 폴 루프시키는)하도록 응용 프로그램을 설계하는 것은 하나의 해결책이다. 그러나이 방법은 응용 프로그램이 결국 서버 이벤트가 완료 여부의 질문에 많은 시간을 써 버리기 때문 그다지 우아가 아닌. 또한 네트워크의 대역폭을 많이 소비되어 버린다.

실현 방법 편집 ]

일반적으로 Web 서버는 클라이언트의 요청을 받으면 즉시 응답을 돌려 준다.

Comet을 이용한 Web 응용 프로그램 서버는 클라이언트의 요청에 즉시 응답하지 않고 보류 상태로두고 서버에서 특정 이벤트 (대화에서 누군가가 발언 한 등)이 발생했을 때 응답을 반환. 이렇게하면 서버에서 발생한 이벤트를 즉시 클라이언트에 보낼 수있다.

관련 항목 편집 ]

외부 링크 편집 ]



출처 - http://en.wikipedia.org/wiki/Comet_(programming)

'Development > JavaScript' 카테고리의 다른 글

javascript - forms 객체  (0) 2013.05.13
socket.io readme  (0) 2012.12.28
자바스크립트 이벤트 핸들링  (0) 2012.12.27
javascript random generate  (0) 2012.12.25
socket.io configure  (0) 2012.12.18
Posted by linuxism
,


소개

이제 당신은 CSS를 이용해서 레이아웃을 잡고 스타일을 주는데에 익숙할 것이다. 그리고 자바스크립트에서 변수와 함수, 메서드 등의 기본적인 개념을 이해하는 첫 발도 내딛었다 – 비록 그 첫 걸음이 좀 비틀거렸을 수도 있겠지만 말이다. 자 이제는, 그러한 지식을 이용해서 당신의 사이트를 방문하는 이용자들에게 상호작용적이면서 역동적인 행동을 제공할 때이다. 자바스크립트를 이용해서 이벤트를 조종하는 것은 당신에게 프랑켄슈타인 박사의 세계로 한걸음 내딛게 하며, 또한 당신의 창조물에게 진실로 생명을 부여하는 일이 될 것이다!

자바스크립트는 충분히 재미 있고, 또한 이 글을 통해 실용성을 갖게 될 것이다 – 이 글에서 당신은 이벤트가 무엇이며 그것을 당신의 페이지에서 어떻게 사용할 수 있는지 배우게 될 것이다. 목차는 다음과 같다:

  • 이벤트란 무엇인가?
  • 이벤트가 움직이는 방법
  • 이벤트의 혁명
    • DOM 레벨 2 이벤트들
    • IE의 이벤트 모델 예외
    • 다양한 브라우저에서 이벤트 등록하기
  • 이벤트와 접근성
  • 이벤트를 조종하기
    • 특정한 요소에 이벤트 적용하기
  • 이벤트 객체 레퍼런스
    • 이벤트에 종속적인 속성들을 체크해보기
  • 이벤트의 기본과 이벤트 버블링
    • 이벤트의 기본적 동작 차단
    • 이벤트 버블링의 중지
  • 완전한 이벤트 제어의 예제
  • 요약
  • 연습문제
이 글에서 사용된 코드 예제들을 다운로드해서 직접 연습해 볼 수 있다는 점을 잊지 말아줬으면 한다.

이벤트란 무엇인가?

웹 페이지에서는 어떤 종류의 상호작용이 발생할 때 이벤트가 일어난다. 사용자가 무언가를 클릭하거나 특정 요소 위로 마우스를 가져가거나 특정한 키를 누르는 것 등이 이러한 상호작용에 포함된다. 이벤트는 또한 브라우저에 의해서도 일어날 수 있는데, 웹 페이지의 로딩이 끝났다거나, 사용자가 페이지를 스크롤하거나, 브라우저 창의 크기를 조절하는 것 등이 포함된다.

자바스크립트의 사용 전체에 걸쳐서 당신은 어떤 특정 이벤트가 일어나는 것을 감지할 수 있으며, 그러한 이벤트들에 대응해서 어떤 일이 일어나게 될지 조합시킬수 있다.

이벤트가 움직이는 방법

웹 페이지 내의 HTML 요소에서 이벤트가 일어나게 되면, 그 요소는 이벤트에 대해 어떤 이벤트 핸들러가 할당되어 있는지 찾아보게 된다. 할당된 이벤트 핸들러가 있다면 적합한 방법으로 그것을 호출하게 되는데, 참조값과 일어난 이벤트에 대한 추가적인 정보들을 함께 전송한다. 그러면 이벤트 핸들러가 동작하게 된다.

이벤트 호출에는 두가지 타입이 있다: 캡춰링capturing과 버블링bubbling이 그것이다.

이벤트 캡춰링은 DOM 트리의 가장 바깥 요소에서부터 시작하여, 이벤트가 일어난 요소에 도착할 때까지 안쪽으로 찾아 들어가고, 다시 바깥으로 나온다. 예를 들어, 웹 페이지에서 무언가를 클릭하면, 처음에는 HTML 요소에서 onclick 이벤트 핸들러를 찾고, 다음에는 body 요소에서 찾고, 다음에는, 다음에는, 하는 식으로, 이벤트가 일어난 요소에 도착할 때까지 반복한다.

이벤트 버블링은 정확히 반대의 방법으로 동작한다: 이벤트가 일어난 요소에서부터 체크 – 이 요소에 뭔가 이벤트 핸들러가 할당되어 있는지 – 를 시작해서, 그 부모 요소로, 그 부모 요소로, 하는 식으로, HTML 요소까지 거슬러 올라간다.

이벤트의 혁명

자바스크립트의 초기에 우리들은 HTML 요소의 내부에서 직접적으로 이벤트 핸들러를 사용했다 – 이렇게 말이다:

  1. <a href="http://www.opera.com/" onclick="alert('Hello')">Say hello</a>

이러한 접근 방법의 문제점은 이벤트 핸들러가 HTML 코드 전체에 섞여있는 것이다. 통제는 불가능에 가까우며, 외부 자바스크립트 파일을 인클루드해 올 때는 웹 브라우저의 캐쉬 기능을 전혀 사용할 수 없게 된다.

혁명적이라고 할 수 있었던 다음 단계는 자바스크립트 블럭에서 이벤트를 적용하게 된 것이다. 예를 들어:

  1. <script type="text/javascript">
  2. document.getElementById("my-link").onclick = waveToAudience;
  3. function waveToAudience() {
  4. alert("Waving like I've never waved before!");
  5. }
  6. </script>
  7. <a id="my-link" href="http://www.opera.com/">My link</a>

마지막 예제에서의 깔끔한 HTML을 주의 깊게 보기 바란다. 이것이 일반적으로 겸손한 자바스크립트라 불리는 것이다. 이러한 깔끔한 HTML은 자바스크립트 캐싱과 코드 컨트롤은 차치하더라도 코드의 분리가 가져다 주는 장점은 크다: 내용이 한 곳에 모여있고, 상호작용을 처리하는 부분이 다른 곳에서 처리되고 있다. 이렇게 해 두면, 설령 자바스크립트가 꺼져 있다 하더라도 링크는 완벽하게 동작하게 되므로 더 높은 접근성을 획득하고, 또한 검색엔진을 기쁘게 할 수 있다.

DOM 레벨 2 이벤트

2000년 11월, W3C에서 Document Object Model (DOM) 레벨 2 이벤트 명세를 발표했다. DOM레벨 2 이벤트는 웹 페이지에서 좀 더 세밀하고 자세하게 이벤트를 제어할 수 있는 방법을 제공한다. HTML 요소들에게 이벤트를 할당하는 새로운 방식은 이와 같은 모양이다:

  1. document.getElementById("my-link").addEventListener("click", myFunction, false);

addEventListener method의 첫번째 매개변수는 이벤트의 이름인데, 접두사 “on” 을 더이상 사용하지 않고 있음을 주의 깊게 보기 바란다. 두번째 매개변수는 이벤트가 발생했을 때 호출하고자 하는 함수에 대한 참조이다. 세번째 매개변수는 이벤트에 대해 useCapture 라 칭하는 제어를 하는데, 쉽게 말해 이벤트 캡춰링을 사용할 것인지 아니면 버블링을 사용할 것인지 정해주는 것이다.

addEventListener의 반대는 removeEventListener이며, HTML 요소에 할당된 모든 이벤트를 제거한다.

IE의 이벤트 모델 예외

불행히도, IE는 DOM 레벨 2 이벤트 모델을 전혀 이행하지 않고 있으며, 그대신 그들만의 독자적인 attachEvent 메서드를 사용하고 있다. 코드는 다음과 같다:

  1. document.getElementById("my-link").attachEvent("onclick", myFunction);
attachEvent 에서는 이벤트의 실제 이름 앞에 on 접두사를 여전히 붙이고 있음을 유의하기 바란다. 그리고 이것은 캡춰링/버블링을 결정할 근거에 대해 어떠한 지원도 하고 있지 않다.

attachEvent의 반대는 detachEvent이며, HTML 요소에 할당된 모든 이벤트를 제거한다.

다양한 브라우저에서 이벤트 등록하기

이벤트 핸들링을 실제 브라우저에 구현함에 있어서 브라우저들 간에 차이가 존재하므로, 모든 유명한 브라우저들에서 공통으로 이벤트 적용이 가능하도록 하는 해결책을 제시하고자 하는 수많은 시도들이 있었다. 이러한 해결책들은 각각 다른 장단점들이 있고, 보통은 addEvent 함수로 불린다.

유명한 자바스크립트 라이브러리들의 거의 대부분이 이러한 것을 포함하고 있으며, 온라인 상에는 이 기능만을 단독으로 갖고 있는 해결책들도 다수 존재한다. 하나 권한다면 Dean Edwards의 addEvent를 권하고 싶은데, jQuery 자바스크립트 라이브러리에서 이벤트를 다루는 옵션들 역시 꼭 읽어봐야 할 만한 것이다.

이벤트와 접근성

이벤트를 어떻게 호출하고 제어할지 더 깊이 파고들기 전에, 잠시 접근성 부분을 강조하고 싶다. 대부분의 사람들에게 접근성은 다소 넓은 주제이지만, 내가 여기에서 말하는 접근성이란, 자바스크립트가 꺼져 있거나 웹 서버에서 차단당하는 경우 등에도 이벤트는 반드시 동작해야 한다는 의미이다.

브라우저에서 자바스크립트를 꺼두는 사람들도 있긴 하지만, 대부분은 프락시 서버나 방화벽, 혹은 광신적인 안티바이러스 프로그램들이 자바스크립트를 프로그래머의 의도대로 동작하지 못하게 막고 있다. 이러한 사실들 때문에 좌절하지 말라: 내 목적은 자바스크립트가 불가능한 상황에서도 사용자가 여전히 사이트를 사용할 수 있게끔 에러처리fallback 옵션을 제공할 수 있도록 당신을 이끄는 것이다.

일반적으로, 특정 이벤트에 대해서 내장된 행동방식을 갖고 있지 않은 HTML 요소들에 이벤트를 할당하지 말아야 한다. 즉, onclick 이벤트는 a 와 같은 요소에만 사용해야 한다 – a 요소는 이미 클릭 이벤트에 대해 에러처리 방법(링크에 정의된 곳으로 이동한다거나, 입력양식을 제출한다거나)을 갖고 있기 때문이다.

이벤트 제어

이벤트의 간단한 예제와 당신이 그것에 대해 어떻게 반응할 수 있는가로부터 시작해보자. 간결함을 위해서 위에 제시했던 addEvent 함수를 사용해서 매 예제마다 크로스 브라우징의 복잡함 속으로 파고드는 일을 피하고자 한다.

우리의 첫번째 예제는 onload 이벤트이다. 이것은 window 객체에 종속된다. 일반적으로, 브라우저 윈도우에 영향을 미치는 모든 이벤트(예를 들어 onload, onresize, onscroll 등)는 window 객체를 통해 제어할 수 있다.

onload 이벤트는 웹 페이지에 포함된 모든것들이 완전히 로드되었을때 발생한다. 모든것이라 함은 HTML 코드 자신과 함께 이미지, CSS파일, 자바스크립트 파일과 같은 외부 참조들을 말한다. 그런것들이 전부 로드되었을때 window.onload 이벤트가 발생하며, 이 이벤트에 대응해서 웹 페이지의 특정 기능이 실행되도록 할 수 있다. 다음의 아주 간단한 예제는 페이지가 로드되었을때 메세지를 보여주는 것이다.

  1. addEvent(window, "load", sayHi);
  2. function sayHi() {
  3. alert("Hello there, stranger!");
  4. }

그다지 나쁘지 않다. 당신이 원한다면, 소위 익명 함수를 사용해서 함수에 이름을 붙이지 않을수도 있다. 이렇게:

  1. addEvent(window, "load", function () {
  2. alert("Hello there, stranger!");
  3. });

특정한 요소에 이벤트 적용하기

이것을 좀 더 확장해보려면, 페이지에 있는 다른 요소들에 이벤트를 할당하는 법에 대해 알아 봐야만 한다. 이러한 논의를 위해 링크를 클릭 할 때마다 특정한 이벤트가 발생하길 원한다고 가정해 보자. 우리가 앞에서 배웠던 것과 이것을 결합해 보면 다음과 같이 하면 될 것이다:

  1. addEvent(window, "load", function () {
  2. var links = document.getElementsByTagName("a");
  3. for (var i=0; i<links.length; i++) {
  4. addEvent(links[i], "click", function () {
  5. alert("NOPE! I won't take you there!");
  6. // This line`s support added through the addEvent function. See below.
  7. evt.preventDefault();
  8. });
  9. }
  10. });

자 무슨 일이 일어났는가? 첫번째로는 onload 이벤트를 사용해서 페이지가 완전히 로딩된 시점을 알아냈다. 다음으로는 document 객체의 getElementsByTagName 메서드를 이용해서 페이지 내에 있는 모든 링크들을 찾아냈다. 이미 참조관계가 만들어져 있으므로, 모든 링크들에 대해 루프를 돌려서 이벤트를 할당했으므로 링크가 클릭될 때마다 액션이 일어난다.

그렇다면 “NOPE! I won`t take you there!”는 조크는 어떻게 된 건가? alert 아래의 줄을 이렇게 읽으면 된다 : return false. 이 문맥 속에서 이 말의 의미는, false를 돌려주는 것은 기본 액션이 실행되지 않도록 막는 것이다.

이벤트 객체 참조

당신의 이벤트 핸들링을 좀 더 자세하게 하기 위해서, 일어나는 이벤트의 특정한 부분별로 다른 액션을 할당해 줄 수 있다. 예를 들어, onkeypress 이벤트를 다루고 있다면, enter 에 대해서만 동작하고 다른 키에 대해서는 동작하지 않게끔 만들고 싶을 수도 있을 것이다.

이벤트 모델에 대해, 다른 모든 브라우저들이 W3C 권고안에 따라 이벤트 객체를 특정(일어난) 이벤트로만 전달하고 있는데 반해, 인터넷 익스플로러는 event 라는, 그들만의 독자적인 전역적 이벤트 객체를 사용하고 있다. 이러한 부분에서 발생하는 가장 흔한 문제는 이벤트 자신에 대한 참조와, 그 이벤트가 가리키고 있는 요소에 대한 참조를 얻는 일이다. 아래의 코드가 이런 부분에서 당신을 도와줄 것이다:

  1. addEvent(document.getElementById("check-it-out"), "click", eventCheck);
  2. function eventCheck (evt) {
  3. var eventReference = (typeof evt !== "undefined")? evt : event;
  4. var eventTarget = (typeof eventReference.target !== "undefined")? eventReference.target : eventReference.srcElement;
  5. }

eventCheck 함수의 첫 줄은 함수로 이벤트 객체가 전달되었는지 체크한다. 전달되었다면, 이벤트는 자동적으로 함수의 첫번째 매개변수가 되고, 이 예제에서는 evt 라는 이름을 갖는다. 전달되지 않았다면, 현재 웹 브라우저가 인터넷 익스플로러라는 뜻이며, window 객체의 전역 속성인 event 를 참조한다.

이벤트 참조가 만들어졌으므로 두번째 줄에서 그것의 target 속성을 찾는다. 존재하지 않는다면, 인터넷 익스플로러가 생성하는 srcElement 를 사용한다.

이러한 제어와 행동은 위에서 언급한 addEvent 함수에서도 다루고 있는데, addEvent 함수에서도 이벤트 객체가 모든 브라우저에서 동작하도록 평준화되고 있다. 위의 코드는 마치 그렇지 않은 것처럼 작성했는데, 브라우저들 간의 차이에 대해 당신이 감각을 가질 수 있게끔 하기 위해서이다.

이벤트에 종속적인 속성 체크

자, 실행에 옮겨 보자. 다음의 코드는 사용자가 누르는 키에 따라 다른 반응을 보인다:

  1. addEvent(document.getElementById("user-name"), "keyup", whatKey);
  2. function whatKey (evt) {
  3. var eventReference = (typeof evt !== "undefined")? evt : event;
  4. var keyCode = eventReference.keyCode;
  5. if (keyCode === 13) {
  6. // The Enter key was pressed
  7. // Code to validate the form and then submit it
  8. }
  9. else if (keyCode === 9) {
  10. // The Tab key was pressed
  11. // Code to, perhaps, clear the field
  12. }
  13. }

whatKey 함수의 코드는 일어난 이벤트의 속성 – keyCode – 을 체크해서, 실제로 눌린 키가 어떤것인지 알아본다. 13이란 숫자는 Enter 키를 의미하고, 9라는 숫자는 Tab 키를 의미한다.

이벤트 기본값과 버블링

이벤트의 기본적인 동작방식을 멈추고 싶은 경우가 아주 많이 있을 것이다. 예를 들어, 입력양식에 공란이 있는채로 제출하는 것을 막고 싶을수 있다. 이벤트 버블링의 경우에도 마찬가지인데, 이러한 상황을 어떻게 제어하는지 알아보도록 하자.

이벤트의 기본적 동작방식 차단

이벤트 모델과 이벤트 객체가 서로 다른 것과 마찬가지로, 이것을 IE에서 하는것과 다른 브라우저에서 하는 두가지 방법이 있다. 앞의 코드에서 이벤트 객체 참조를 찾아내는 코드를 작성했으므로, 이번에는 링크가 클릭되었을 때 링크 요소의 기본적인 동작방식을 막는 코드를 만들어보겠다.

  1. addEvent(document.getElementById("stop-default"), "click", stopDefaultBehavior);
  2. function stopDefaultBehavior (evt) {
  3. var eventReference = (typeof evt !== "undefined")? evt : event;
  4. if (eventReference.preventDefault) {
  5. eventReference.preventDefault();
  6. }
  7. else {
  8. eventReference.returnValue = false;
  9. }
  10. }

위의 접근방법은 소위 디텍션, 이라 칭하는 것을 사용하는데, 메서드를 호출하기 전에 먼저 그것이 사용가능한지를 체크함으로서 에러를 막는 방법이다. preventDefault 메서드는 IE를 제외한 모든 브라우저에서 동작하며, 이것은 이벤트의 기본 동작이 일어나는 것을 막는다.

만약 이 메서드가 지원되지 않는다면, 전역 이벤트 객체의 returnValue 속성에 false 값을 할당하고, 따라서 이것이 IE에서 (이벤트의)기본 동작을 막아줄 것이다.

이벤트 버블링의 중지

다음 HTML의 계층구조를 음미해 보자:

  1. <div>
  2. <ul>
  3. <li>
  4. <a href="http://www.opera.com/">Opera</a>
  5. </li>
  6. <li>
  7. <a href="http://www.opera.com/products/dragonfly/">Opera Dragonfly</a>
  8. </li>
  9. </ul>
  10. </div>

a, li, ul 요소 모두에게 onclick 이벤트를 할당했다고 가정해보자. onclick 이벤트는 가장 먼저 링크의 이벤트 핸들러를 호출할 것이고, 다음으로 li, 다음으로 ul의 이벤트 핸들러를 호출할 것이다.

아마도, 사용자는 링크를 클릭할 것인데, 링크의 부모 요소인 li에 할당된 어떤 이벤트 핸들러도 동작하지 않게끔 하고 싶을 것이다. 반대로, 사용자가 링크가 아니라 그 옆에 있는 li 를 클릭한 경우에는 li 뿐 아니라 ul 요소에 할당한 이벤트 핸들러도 함께 동작하게끔 하고 싶을 수 있다.

DOM 레벨 2 이벤트 모델을 사용하고 useCapture 를 켜 뒀다면 – 다시 말해, 이벤트 캡춰링을 사용하고 있다면 – , ul → li → 링크 순서가 될 것임을 기억해 두기 바란다. 그렇긴 한데, IE는 이벤트 캡춰링을 지원하지 않으므로, 이런 일이 현실에서 일어나는 경우는 지극히 드물 것이다.

이벤트 버블링을 막기 위한 코드가 여기 준비되어 있다:

  1. addEvent(document.getElementById("stop-default"), "click", cancelEventBubbling);
  2. function cancelEventBubbling (evt) {
  3. var eventReference = (typeof evt !== "undefined")? evt : event;
  4. if (eventReference.stopPropagation) {
  5. eventReference.stopPropagation();
  6. }
  7. else {
  8. eventReference.cancelBubble = true;
  9. }
  10. }

이벤트 핸들링의 완전한 예제

이벤트 핸들러를 추가하고, 특정 상황에서는 해당 이벤트의 기본동작을 막는, 예제 페이지 를 동봉하였다. 이벤트 핸들러는 사용자가 모든 필드를 작성하였는가 에 따라 폼이 제출될 수 있는지의 여부를 판단한다. 자바스크립트 코드는 다음과 같다:

  1. addEvent(window, "load", function () {
  2. var contactForm = document.getElementById("contact-form");
  3. if (contactForm) {
  4. addEvent(contactForm, "submit", function (evt) {
  5. var firstName = document.getElementById("first-name");
  6. var lastName = document.getElementById("last-name");
  7. if (firstName && lastName) {
  8. if (firstName.value.length === 0 || lastName.value.length === 0) {
  9. alert("You have to fill in all fields, please.");
  10. evt.preventDefault();
  11. }
  12. }
  13. });
  14. }
  15. });

요약

이 글에서는 이벤트 핸들링의 아주 기초적인 부분만을 다루었지만, 이벤트가 어떻게 동작하는지에 대해 잘 이해해주었기를 바란다. 브라우저 간의 비호환성을 다룬 것이 당신에게 조금 어렵게 느껴졌을수도 있겠지만, 내가 생각하기에 시작부터 이러한 문제들을 인식한다는 것은 대단히 중요하다.

일단 당신이 이러한 문제들을 인식하고, 위에서 제시한 해결책들을 마스터했다면, 당신은 자바스크립트와 이벤트 핸들링을 가지고 무엇이든 해낼 수 있을 것이다!

연습문제

  • 이벤트란 무엇인가?
  • 이벤트 캡춰링과 버블링의 차이는 무엇인가?
  • 이벤트의 실행을 제어할 수 있는가? 다시 말해, 그 기본적인 동작방식을 차단할 수 있는가? 어떻게 가능한가?
  • 자바스크립트 웹 커뮤니티를 들뜨게 한, attachEvent 와 scope 의 차이는 무엇인가?

저자에 대해

Robert Nyman은 웹 인터페이스 개발 분야에서 10년 동안 일해오고 있으며, 그가 가장 관심있어 한 주제는 자바스크립트이다. 그는 자신의 블로그, Robert’s talk에 웹 개발에 대해 열성적으로 포스팅하고 있다.

그는 스웨덴에서 멋진 가족들과 함께 살고 있으며, 종종 가족들이 잠든 늦은 시간까지 집필에 힘쓴다. 또한 그가 꿈꾸고 있는 비밀스러운 소망은, 언젠가는 돈을 많이 벌어서 웹 세계의 경계를 넘어 현실 세계에 대한 글을 써 보는 것이다.


출처 - http://www.clearboth.org/49_handling-events-with-javascript/


'Development > JavaScript' 카테고리의 다른 글

socket.io readme  (0) 2012.12.28
comet  (0) 2012.12.28
javascript random generate  (0) 2012.12.25
socket.io configure  (0) 2012.12.18
javascript - 클로저(Closure)  (0) 2012.12.01
Posted by linuxism
,


윈도우7 사용자가 리눅스를 같이 사용하는 길은 대략 2가지가 있겠다. 

1. 윈도우/리눅스 듀얼 부팅
  - 먼저 윈도우를 설치하고, 제어판으로 가서 디스크 관리자에서 볼륨 축소 기능을 이용해서 리눅스를 쓰기 위한 공간을 확보
  - 최강의 듀얼 부팅 프로그램인 EasyBCD를 받아 설치
     EasyBCD 홈페이지
  - 리눅스 CD 또는 DVD로 부팅하여 빈 파티션에 리눅스를 설치
  - 윈도우로 부팅한 후 EasyBCD를 실행해서 리눅스 듀얼 부팅을 설정(클릭 몇번만 하면 되므로 매우 쉽다)
  - 재부팅하면 윈도우 부트 메뉴에서 윈도우/리눅스 선택이 가능
    
2. 가상 머신 사용
  - 윈도우 설치
  - 걸출한 공짜 가상 머신 프로그램인 VirtualBox 설치
    VirtualBox 홈페이지
  - 가상 머신을 생성하고 리눅스 설치(리눅스를 굳이 CD로 굽지 않고 iso 파일로 설치할 수 있어서 편리하다)
  - 가상머신에서 VirtualBox Additions 설치(이걸 해 줘야 호스트와의 파일 공유, 화면 해상도 변경 등이 가능하다)
  * 리눅스에서 VirtualBox Additions 설치가 배포판에 따라 약간 껄끄러울 수가 있는데, 이 부분은 나중에 별도의 게시물로 써 놔야 겠다.


EasyBCD 2.1.2.zip


출처 - http://bahndal.egloos.com/88140



'System > Windows' 카테고리의 다른 글

batch에서 현재 경로 확인  (0) 2012.12.22
batch 명령어  (0) 2012.12.22
batch 명령어 모음  (0) 2012.12.22
window - TASKKILL(process kill)  (0) 2012.12.22
java - windows dos 명령어, exe 및 bat 파일 실행  (0) 2012.12.21
Posted by linuxism
,