Permalink
Browse files

Add documentation for `Element.Layout` and `Event.on`.

  • Loading branch information...
1 parent 23a1444 commit 14e794384e7bf89028e5e6627dcba54d2f796366 @savetheclocktower savetheclocktower committed Nov 15, 2010
Showing with 126 additions and 4 deletions.
  1. +62 −1 src/dom/event.js
  2. +64 −3 src/dom/layout.js
View
@@ -937,6 +937,7 @@
* avoids adding an observer to a number of individual elements and instead
* listens on a _common ancestor_ element.
*
+ * For more information on usage, see [[Event.on]].
**/
Event.Handler = Class.create({
/**
@@ -992,14 +993,69 @@
});
/**
- * Event.on(element, eventName, selector, callback) -> Event.Handler
+ * Event.on(element, eventName[, selector], callback) -> Event.Handler
+ * - element (Element | String): The DOM element to observe, or its ID.
+ * - eventName (String): The name of the event, in all lower case, without
+ * the "on" prefix — e.g., "click" (not "onclick").
+ * - selector (String): A CSS selector. If specified, will call `callback`
+ * _only_ when it can find an element that matches `selector` somewhere
+ * in the ancestor chain between the event's target element and the
+ * given `element`.
+ * - callback (Function): The event handler function. Should expect two
+ * arguments: the event object _and_ the element that received the
+ * event. (If `selector` was given, this element will be the one that
+ * satisfies the criteria described just above; if not, it will be the
+ * one specified in the `element` argument). This function is **always**
+ * bound to `element`.
*
* Listens for events on an element's descendants, optionally filtering
* to match a given CSS selector.
*
* Creates an instance of [[Event.Handler]], calls [[Event.Handler#start]],
* then returns that instance. Keep a reference to this returned instance if
* you later want to unregister the observer.
+ *
+ * ##### Usage
+ *
+ * `Event.on` can be used to set up event handlers with or without event
+ * delegation. In its simplest form, it works just like [[Event.observe]]:
+ *
+ * $("messages").on("click", function(event) {
+ * // ...
+ * });
+ *
+ * An optional second argument lets you specify a CSS selector for event
+ * delegation. This encapsulates the pattern of using [[Event#findElement]]
+ * to retrieve the first ancestor element matching a specific selector.
+ *
+ * $("messages").on("click", "a.comment", function(event, element) {
+ * // ...
+ * });
+ *
+ * Note the second argument in the handler above: it references the
+ * element matched by the selector (in this case, an `a` tag with a class
+ * of `comment`). This argument is important to use because within the
+ * callback, the `this` keyword **will always refer to the original
+ * element** (in this case, the element with the id of `messages`).
+ *
+ * `Event.on` differs from `Event.observe` in one other important way:
+ * its return value is an instance of [[Event.Handler]]. This instance
+ * has a `stop` method that will remove the event handler when invoked
+ * (and a `start` method that will attach the event handler again after
+ * it's been removed).
+ *
+ * // Register the handler:
+ * var handler = $("messages").on("click", "a.comment",
+ * this.click.bind(this));
+ *
+ * // Unregister the handler:
+ * handler.stop();
+ *
+ * // Re-register the handler:
+ * handler.start();
+ *
+ * This means that, unlike `Event.stopObserving`, there's no need to
+ * retain a reference to the handler function.
**/
function on(element, eventName, selector, callback) {
element = $(element);
@@ -1146,6 +1202,11 @@
**/
stopObserving: stopObserving.methodize(),
+ /**
+ * Element.on(@element, eventName[, selector], callback) -> Event.Handler
+ *
+ * See [[Event.on]].
+ **/
on: on.methodize(),
/**
View
@@ -224,9 +224,10 @@
**/
Element.Layout = Class.create(Hash, {
/**
- * new Element.Layout(element[, preCompute])
+ * new Element.Layout(element[, preCompute = false])
* - element (Element): The element to be measured.
- * - preCompute (Boolean): Whether to compute all values at once.
+ * - preCompute (Boolean): Whether to compute all values at once. Default
+ * is `false`.
*
* Declare a new layout hash.
*
@@ -273,6 +274,11 @@
*
* Retrieve the measurement specified by `property`. Will throw an error
* if the property is invalid.
+ *
+ * ##### Caveats
+ *
+ * * `Element.Layout` can measure the dimensions of an element hidden with
+ * CSS (`display: none`), but _only_ if its parent element is visible.
**/
get: function($super, property) {
// Try to fetch from the cache.
@@ -386,6 +392,10 @@
*
* Keys can be passed into this method as individual arguments _or_
* separated by spaces within a string.
+ *
+ * // Equivalent statements:
+ * someLayout.toObject('top', 'bottom', 'left', 'right');
+ * someLayout.toObject('top bottom left right');
**/
toObject: function() {
var args = $A(arguments);
@@ -410,6 +420,10 @@
*
* Keys can be passed into this method as individual arguments _or_
* separated by spaces within a string.
+ *
+ * // Equivalent statements:
+ * someLayout.toHash('top', 'bottom', 'left', 'right');
+ * someLayout.toHash('top bottom left right');
**/
toHash: function() {
var obj = this.toObject.apply(this, arguments);
@@ -712,6 +726,8 @@
/**
* Element.Offset#inspect() -> String
+ *
+ * Returns a debug-friendly representation of the offset.
**/
inspect: function() {
return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this);
@@ -726,14 +742,19 @@
/**
* Element.Offset#toArray() -> Array
+ *
+ * Returns an array representation fo the offset in [x, y] format.
**/
toArray: function() {
return [this.left, this.top];
}
});
/**
- * Element.getLayout(@element, preCompute) -> Element.Layout
+ * Element.getLayout(@element[, preCompute = false]) -> Element.Layout
+ * - element (Element): The element to be measured.
+ * - preCompute (Boolean): Whether to compute all values at once. Default
+ * is `false`.
*
* Returns an instance of [[Element.Layout]] for measuring an element's
* dimensions.
@@ -744,6 +765,35 @@
* `Element.getLayout` whenever you need a measurement. You should call
* `Element.getLayout` again only when the values in an existing
* `Element.Layout` object have become outdated.
+ *
+ * Remember that instances of `Element.Layout` compute values the first
+ * time they're asked for and remember those values for later retrieval.
+ * If you want to compute all an element's measurements at once, pass
+ *
+ * ##### Examples
+ *
+ * var layout = $('troz').getLayout();
+ *
+ * layout.get('width'); //-> 150
+ * layout.get('height'); //-> 500
+ * layout.get('padding-left'); //-> 10
+ * layout.get('margin-left'); //-> 25
+ * layout.get('border-top'); //-> 5
+ * layout.get('border-bottom'); //-> 5
+ *
+ * // Won't re-compute width; remembers value from first time.
+ * layout.get('width'); //-> 150
+ *
+ * // Composite values obtained by adding together other properties;
+ * // will re-use any values we've already looked up above.
+ * layout.get('padding-box-width'); //-> 170
+ * layout.get('border-box-height'); //-> 510
+ *
+ * ##### Caveats
+ *
+ * * Instances of `Element.Layout` can measure the dimensions of an
+ * element hidden with CSS (`display: none`), but _only_ if its parent
+ * element is visible.
**/
function getLayout(element, preCompute) {
return new Element.Layout(element, preCompute);
@@ -759,6 +809,17 @@
* calling this method frequently over short spans of code, you might want
* to call [[Element.getLayout]] and operate on the [[Element.Layout]]
* object itself (thereby taking advantage of measurement caching).
+ *
+ * ##### Examples
+ *
+ * $('troz').measure('width'); //-> 150
+ * $('troz').measure('border-top'); //-> 5
+ * $('troz').measure('top'); //-> 226
+ *
+ * ##### Caveats
+ *
+ * * `Element.measure` can measure the dimensions of an element hidden with
+ * CSS (`display: none`), but _only_ if its parent element is visible.
**/
function measure(element, property) {
return $(element).getLayout().get(property);

0 comments on commit 14e7943

Please sign in to comment.