1 .. title:: MochiKit.Signal - Simple universal event handling
2 .. |---| unicode:: U+2014 .. em dash, trimming surrounding whitespace
8 MochiKit.Signal - Simple universal event handling
14 Signal for DOM events::
16 // DOM events are also signals. Connect freely! The functions will be
17 // called with the custom event as a parameter.
19 // calls myClicked.apply(getElement('myID'), [event])
20 connect('myID', 'onclick', myClicked);
22 // calls wasClicked.apply(myObject, [event])
23 connect('myID', 'onclick', myObject, wasClicked);
25 // calls myObject.wasClicked(event)
26 connect('myID', 'onclick', myObject, 'wasClicked');
28 // the event is normalized, no more e = e || window.event!
29 myObject.wasClicked = function(e) {
30 var crossBrowserCoordinates = e.mouse().page;
31 // e.mouse().page is a MochiKit.Style.Coordinates object
35 Signal for non-DOM events::
37 // otherObject.gotFlash() will be called when 'flash' signalled.
38 connect(myObject, 'flash', otherObject, 'gotFlash');
40 // gotBang.apply(otherObject, [...]) will be called when 'bang' signalled.
41 // You can access otherObject from within gotBang as 'this'.
42 connect(myObject, 'bang', otherObject, gotBang);
44 // myFunc.apply(myObject, [...]) will be called when 'flash' signalled.
45 // You can access myObject from within myFunc as 'this'.
46 var ident = connect(myObject, 'flash', myFunc);
48 // You may disconnect with the return value from connect
51 // Signal can take parameters. These will be passed along to the
52 // connected functions.
53 signal(myObject, 'flash');
54 signal(myObject, 'bang', 'BANG!');
60 Event handling was never so easy!
62 This module takes care of all the hard work |---| figuring out which
63 event model to use, trying to retrieve the event object, and handling
64 your own internal events, as well as cleanup when the page is unloaded
65 to clean up IE's nasty memory leakage.
67 This event system is largely based on Qt's signal/slot system. Read
68 more on how that is handled and also how it is used in model/view
69 programming at: http://doc.trolltech.com/
75 - :mochiref:`MochiKit.Base`
76 - :mochiref:`MochiKit.DOM`
82 Using Signal for DOM Events
83 ---------------------------
85 When using MochiKit.Signal, do not use the browser's native event
86 API. That means, no ``onclick="blah"``, no
87 ``elem.addEventListener(...)``, and certainly no
88 ``elem.attachEvent(...)``. This also means that
89 :mochiref:`MochiKit.DOM.addToCallStack` and
90 :mochiref:`MochiKit.DOM.addLoadEvent` should not be used in
91 combination with this module.
93 Signals for DOM objects are named with the ``'on'`` prefix, e.g.:
94 ``'onclick'``, ``'onkeyup'``, etc.
96 When the signal fires, your slot will be called with one parameter,
97 the custom event object.
100 Custom Event Objects for DOM events
101 -----------------------------------
103 Signals triggered by DOM events are called with a custom event object
104 as a parameter. The custom event object presents a consistent view of
105 the event across all supported platforms and browsers, and provides
106 many conveniences not available even in a correct W3C implementation.
108 See the `DOM Custom Event Object Reference`_ for a detailed API
109 description of this object.
111 If you find that you're accessing the native event for any reason,
112 create a `new ticket`_ and we'll look into normalizing the behavior
115 .. _`new ticket`: http://trac.mochikit.com/newticket
116 .. _`Safari bug 6595`: http://bugs.webkit.org/show_bug.cgi?id=6595
117 .. _`Safari bug 7790`: http://bugs.webkit.org/show_bug.cgi?id=7790
118 .. _`Safari bug 8707`: http://bugs.webkit.org/show_bug.cgi?id=8707
119 .. _`stopPropagation()`: http://developer.mozilla.org/en/docs/DOM:event.stopPropagation
120 .. _`preventDefault()`: http://developer.mozilla.org/en/docs/DOM:event.preventDefault
126 Any object that has connected slots (via :mochiref:`connect()`) is
127 referenced by the Signal mechanism until it is disconnected via
128 :mochiref:`disconnect()` or :mochiref:`disconnectAll()`.
130 Signal does not leak. It registers an ``'onunload'`` event that
131 disconnects all objects on the page when the browser leaves the
132 page. However, memory usage will grow during the page view for every
133 connection made until it is disconnected. Even if the DOM object is
134 removed from the document, it will still be referenced by Signal until
135 it is explicitly disconnected.
137 In order to conserve memory during the page view,
138 :mochiref:`disconnectAll()` any DOM elements that are about to be
139 removed from the document.
145 Certain events supported by MochiKit are not generated natively by all
146 browsers. MochiKit can synthesize these events even for non-supporting
147 browsers, however, by watching for related events and triggering the
148 appropriate signals at the right times.
150 These events include:
154 Similar to ``'onmouseover'``, but does not "bubble" up to parent
155 nodes. Such bubbling is often a cause of confusion. On an
156 ``'onmouseenter'`` event, you can be certain that the mouse has
157 left the node attached to the event.
160 Available in MochiKit 1.4+
164 Similar to ``'onmouseout'``, but does not "bubble" up to parent
165 nodes. This is the analog to ``'onmouseenter'``.
168 Available in MochiKit 1.4+
171 Using Signal for non-DOM objects
172 --------------------------------
174 Signals are triggered with the :mochiref:`signal(src, 'signal', ...)`
175 function. Additional parameters passed to this are passed onto the
176 connected slots. Explicit signals are not required for DOM events.
178 Slots that are connected to a signal are called in the following
179 manner when that signal is signalled:
181 - If the slot was a single function, then it is called with ``this``
182 set to the object originating the signal with whatever parameters
183 it was signalled with.
185 - If the slot was an object and a function, then it is called with
186 ``this`` set to the object, and with whatever parameters it was
189 - If the slot was an object and a string, then ``object[string]`` is
190 called with the parameters to the signal.
200 :mochidef:`connect(src, signal, dest[, func])`:
202 Connects a signal to a slot, and return a unique identifier that
203 can be used to disconnect that signal.
205 ``src`` is the object that has the signal. You may pass in a
206 string, in which case, it is interpreted as an id for an HTML
209 ``signal`` is a string that represents a signal name. If 'src' is
210 an HTML Element, ``window``, or the ``document``, then it can be
211 one of the 'on-XYZ' events. You must include the 'on' prefix, and
212 it must be all lower-case.
214 ``dest`` and ``func`` describe the slot, or the action to take
215 when the signal is triggered.
217 - If ``dest`` is an object and ``func`` is a string, then
218 ``dest[func].apply(dest, [...])`` will be called when the
221 - If ``dest`` is an object and ``func`` is a function, then
222 ``func.apply(dest, [...])`` will be called when the signal
225 - If ``func`` is undefined and ``dest`` is a function, then
226 ``dest.apply(src, [...])`` will be called when the signal is
229 No other combinations are allowed and will raise an exception.
231 The return value can be passed to :mochiref:`disconnect` to
232 disconnect the signal.
234 In MochiKit 1.4+, if ``src`` is an object that has a ``__connect__``
235 method, then ``src.__connect__(ident, signal, objOrFunc, funcOrStr)``
236 will be called. This method may be used to disconnect the signal.
237 DOM objects can not implement this feature.
240 Available in MochiKit 1.3.1+
243 :mochidef:`disconnect(ident)`:
245 To disconnect a signal, pass its ident returned by
246 :mochiref:`connect()`. This is similar to how the browser's
247 ``setTimeout`` and ``clearTimeout`` works.
250 Available in MochiKit 1.3.1+
253 :mochidef:`disconnectAll(src[, signal, ...])`:
255 ``disconnectAll(src)`` removes all signals from src.
257 ``disconnectAll(src, 'onmousedown', 'mySignal')`` will remove all
258 ``'onmousedown'`` and ``'mySignal'`` signals from src.
261 Available in MochiKit 1.3.1+
264 :mochidef:`disconnectAllTo(dest[, func])`:
266 ``disconnectAllTo(dest)`` removes all signals connected to dest.
268 ``disconnectAllTo(dest, func)`` will remove all
269 signals connected to dest using func.
272 Available in MochiKit 1.4+
275 :mochidef:`signal(src, signal, ...)`:
277 This will signal a signal, passing whatever additional parameters
278 on to the connected slots. ``src`` and ``signal`` are the same as
279 for :mochiref:`connect()`.
282 Available in MochiKit 1.3.1+
285 DOM Custom Event Object Reference
286 ---------------------------------
290 The native event produced by the browser. You should not need to
294 Available in MochiKit 1.3.1+
299 The element that this signal is connected to.
302 Available in MochiKit 1.3.1+
307 The event type (``'click'``, ``'mouseover'``, ``'keypress'``,
308 etc.) as a string. Does not include the ``'on'`` prefix.
311 Available in MochiKit 1.3.1+
314 :mochidef:`target()`:
316 The element that triggered the event. This may be a child of
320 Available in MochiKit 1.3.1+
323 :mochidef:`modifier()`:
325 Returns ``{shift, ctrl, meta, alt, any}``, where each property is
326 ``true`` if its respective modifier key was pressed, ``false``
327 otherwise. ``any`` is ``true`` if any modifier is pressed,
331 Available in MochiKit 1.3.1+
334 :mochidef:`stopPropagation()`:
336 Works like W3C's `stopPropagation()`_.
339 Available in MochiKit 1.3.1+
342 :mochidef:`preventDefault()`:
344 Works like W3C's `preventDefault()`_.
347 Available in MochiKit 1.3.1+
352 Shortcut that calls ``stopPropagation()`` and
353 ``preventDefault()``.
356 Available in MochiKit 1.3.1+
361 Returns ``{code, string}``.
363 Use ``'onkeydown'`` and ``'onkeyup'`` handlers to detect control
364 characters such as ``'KEY_F1'``. Use the ``'onkeypress'``
365 handler to detect "printable" characters, such as ``'é'``.
367 When a user presses F1, in ``'onkeydown'`` and ``'onkeyup'`` this
368 method returns ``{code: 122, string: 'KEY_F1'}``. In
369 ``'onkeypress'``, it returns ``{code: 0, string: ''}``.
371 If a user presses Shift+2 on a US keyboard, this method returns
372 ``{code: 50, string: 'KEY_2'}`` in ``'onkeydown'`` and
373 ``'onkeyup'``. In ``'onkeypress'``, it returns ``{code: 64,
376 See ``_specialKeys`` in the source code for a comprehensive list
377 of control characters.
380 Available in MochiKit 1.3.1+
385 Properties for ``'onmouse*'``, ``'onclick'``, ``'ondblclick'``,
386 and ``'oncontextmenu'``:
388 - ``page`` is a :mochiref:`MochiKit.Style.Coordinates` object
389 that represents the cursor position relative to the HTML
390 document. Equivalent to ``pageX`` and ``pageY`` in
391 Safari, Mozilla, and Opera.
393 - ``client`` is a :mochiref:`MochiKit.Style.Coordinates`
394 object that represents the cursor position relative to the
395 visible portion of the HTML document. Equivalent to
396 ``clientX`` and ``clientY`` on all browsers. Current versions of
397 Safari incorrectly return clientX as relative to the canvas
398 instead of relative to the viewport (`Safari Bug 8707`_).
400 Properties for ``'onmouseup'``, ``'onmousedown'``, ``'onclick'``,
401 and ``'ondblclick'``:
403 - ``mouse().button`` returns ``{left, right, middle}`` where
404 each property is ``true`` if the mouse button was pressed,
409 - Current versions of Safari won't signal ``'ondblclick'``
410 when attached via ``connect()`` (`Safari Bug 7790`_).
412 - In Safari < 2.0.4, calling ``preventDefault()`` or ``stop()``
413 in ``'onclick'`` events signalled from ``<a>`` tags does not
414 prevent the browser from following those links.
416 - Mac browsers don't report right-click consistently. Firefox
417 signals the slot and sets ``modifier().ctrl`` to true,
418 Opera signals the slot and sets ``modifier().meta`` to
419 ``true``, and Safari doesn't signal the slot at all
420 (`Safari Bug 6595`_).
422 To find a right-click in Safari, Firefox, and IE, you can
423 connect an element to ``'oncontextmenu'``. This doesn't
427 Available in MochiKit 1.3.1+
430 :mochidef:`relatedTarget()`:
432 Returns the document element that the mouse has moved to. This is
433 generated for ``'onmouseover'`` and ``'onmouseout'`` events.
436 Available in MochiKit 1.3.1+
439 :mochidef:`confirmUnload(msg)`:
441 In browsers that support the ``'onbeforeunload'`` event (IE and
442 Firefox), calling this in the event handler will show a dialog box
443 that allows the user to confirm or cancel the navigation away from
447 Available in MochiKit 1.4+
453 - Jonathan Gardner <jgardner@jonathangardner.net>
454 - Beau Hartshorne <beau@hartshornesoftware.com>
455 - Bob Ippolito <bob@redivi.com>
461 Copyright 2006 Jonathan Gardner <jgardner@jonathangardner.net>, Beau
462 Hartshorne <beau@hartshornesoftware.com>, and Bob Ippolito
463 <bob@redivi.com>. This program is dual-licensed free software; you
464 can redistribute it and/or modify it under the terms of the `MIT
465 License`_ or the `Academic Free License v2.1`_.
467 .. _`MIT License`: http://www.opensource.org/licenses/mit-license.php
468 .. _`Academic Free License v2.1`: http://www.opensource.org/licenses/afl-2.1.php