Skip to content

Commit

Permalink
Updated documentation for delegate() and capture option
Browse files Browse the repository at this point in the history
  • Loading branch information
jherax committed Oct 17, 2017
1 parent 0fbfcbb commit 82d6954
Show file tree
Hide file tree
Showing 10 changed files with 371 additions and 234 deletions.
120 changes: 80 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ $ yarn add handle-events
<script src="https://unpkg.com/handle-events/dist/handle-events.min.js"></script>

<!-- or from rawgit.com -->
<script src="https://cdn.rawgit.com/jherax/handle-events/1.0.0/dist/handle-events.min.js"></script>
<script src="https://cdn.rawgit.com/jherax/handle-events/1.1.0/dist/handle-events.min.js"></script>
```

In the above case, the library will be included as global object in
the browser under the name of [`jsu`](#examples), wherein, if that
namespace exists, it will be extended, otherwise a new `jsu` object
will be created.
In the above case, the library will be included as global object
in the browser under the name of [`jsu`](#api) (JavaScript-Utils),
wherein, if that namespace exists, it will be extended, otherwise
a new `jsu` object will be created.

As this library is built as [UMD] _(Universal Module Definition)_, it
can be included from module loaders such as [CommonJS], [ES2015 Imports]
Expand All @@ -49,13 +49,13 @@ or [AMD RequireJS].
### CommonJS

```javascript
var evt = require('handle-events');
var jsu = require('handle-events');
```

### ES2015 Imports

```javascript
import evt from 'handle-events';
import jsu from 'handle-events';
```

### AMD
Expand All @@ -68,8 +68,8 @@ requirejs.config({
'handle-events': '<PATH>/handle-events.min'
}
});
require(['handle-events'], function(evt) {
console.log(evt);
require(['handle-events'], function(jsu) {
console.log(jsu);
});
```

Expand All @@ -81,28 +81,28 @@ See an example with RequireJS here: http://jsfiddle.net/FdKTn/78/

## API

- [addEventListener](#addeventlistenernode-eventns-listener-usecapture)
- [delegate](#delegatenode-selector-eventns-listener-usecapture)
- [addEventListener](#addeventlistenernode-eventns-listener-capture)
- [delegate](#delegatenode-selector-eventns-listener-capture)
- [removeEventListener](#removeeventlistenernode-eventns-listener)
- [getEventListeners](#geteventlistenersnode-eventns)
- [handleEvents](#handleeventsnode)

### addEventListener(node, eventns, listener, useCapture)
### addEventListener(node, eventns, listener, capture)

**Returns `void`**

```javascript
addEventListener(node: Element, eventns: String, listener: Function, useCapture: Boolean) : void
addEventListener(node: Element, eventns: String, listener: Function, capture: Boolean) : void
```

Attaches an event-handler to a DOM element. You can set a namespace to
the event by appending a dot `.` to the event name.
It receives the following arguments:

- **node** `Element`: DOM Element to which the event handler is attached
- **eventns** `String`: name of the event.namespace to register
- **listener** `Function`: event handler
- **useCapture** `Function`: event capture (default false)
- **eventns** `String`: name of the event (with .namespace) to register
- **listener** `Function`: the function which receives the event notification
- **capture** `Boolean`: if the event is activated at the beginning _(default `false`)_

Each event handler attached is tracked by an internal store, which keeps track
of the event type and the namespace linked to a DOM Element. You can access
Expand All @@ -111,34 +111,74 @@ that store through the API [getEventListeners](#geteventlistenersnode-eventns).
```javascript
var title = document.getElementById('title');

// add a named event handler + namespace (recommended)
// add a named event handler with namespace (recommended)
const onMouseOver = (e) => console.log(`triggered ${e.type}.tooltip`);
jsu.addEventListener(title, 'mouseover.tooltip', onMouseOver);

// add an anonymous event handler
// add an anonymous event handler (without namespace)
jsu.addEventListener(title, 'click', (e) => {
console.log(`triggered ${e.type}`);
});
```

Events can be activated at two occasions: At the beginning _("capture")_ by
setting `capture = true`, and at the end _("bubble")_ by default.
Events are executed in the order of how they're defined.

Say, you define 4 event listeners:

```javascript
jsu.addEventListener(document, "click", (e) => alert(1));
jsu.addEventListener(document, "click", (e) => alert(2), true);
jsu.addEventListener(document, "click", (e) => alert(3), false);
jsu.addEventListener(document, "click", (e) => alert(4), true);
```

The alert boxes will pop up in this order:

- `2`: defined first, using `capture = true`
- `4`: defined second, using `capture = true`
- `1`: first handler defined without setting `capture`
- `3`: second handler defined with `capture = false`

For a better understanding of capture-events and event-bubbling,
read the following link: https://stackoverflow.com/a/10654134/2247494
and also you can see a demo here: http://jsfiddle.net/sc5Xa/198/

[&#9751; Back to API](#api)

### delegate(node, selector, eventns, listener, useCapture)
### delegate(node, selector, eventns, listener, capture)

**Returns `void`**

```javascript
delegate(node: Element, selector: String, eventns: String, listener: function, useCapture: Boolean): voide
delegate(node: Element, eventns: String, selector: String, listener: Function, capture: Boolean) : void
```

Attaches an event-handler to a Dom Element but delegates the event the selector.
Attaches a listener to a DOM `Element` but delegates the event-listener
to the DOM Elements beneath that matches with the `selector` provided.
It receives the following arguments:

- **node** `Element`: DOM Element to which the event handler is attached
- **eventns** `String`: name of the event.namespace to register
- **selector** `String`: CSS Selector
- **listener** `Function`: event handler
- **useCapture** `Function`: event capture (default false)
- **eventns** `String`: name of the event (with .namespace) to register
- **selector** `String`: CSS selector for those elements that will propagate the event
- **listener** `Function`: the function which receives the event notification
- **capture** `Boolean`: if the event is activated at the beginning _(default `false`)_

**Returns `void`**
Events can be activated at two occasions: At the beginning _("capture")_ by
setting `capture = true`, and at the end _("bubble")_ by default.
Events are executed in the order of how they're defined.

```javascript
jsu.delegate(document, "click.test", "h3", (e) => alert(1));
jsu.delegate(document, "click.test", "h3", (e) => alert(2), true);
jsu.delegate(document, "click.test", "h3", (e) => alert(3), false);
jsu.delegate(document, "click.test", "h3", (e) => alert(4), true);
```

For a better understanding of capture-events and event-bubbling,
read the following link: https://stackoverflow.com/a/10654134/2247494
and also you can see a demo here: http://jsfiddle.net/sc5Xa/198/

[&#9751; Back to API](#api)

Expand All @@ -159,13 +199,13 @@ only a namespace that will match with all event types.
It receives the following arguments:

- **node** `Element`: DOM element where the event handler is removed.
- **eventns** `String`: _(optional)_ name of the event.namespace to remove.
- **listener** `Function`: _(optional)_ event handler.
- **eventns** `String`: _(optional)_ name of the event (with .namespace) to remove
- **listener** `Function`: _(optional)_ the function which receives the event notification

Each event handler attached by
[addEventListener](#addeventlistenernode-eventns-listener) is tracked by an
internal store, which keeps track of the event type and the namespace linked
to a DOM Element. You can access that store through the API
[addEventListener](#addeventlistenernode-eventns-listener-capture) is tracked
by an internal store, which keeps track of the event type and the namespace
linked to a DOM Element. You can access that store through the API
[getEventListeners](#geteventlistenersnode-eventns).

```javascript
Expand All @@ -190,9 +230,9 @@ getEventListeners(node: Element) : Object
```

Gets all event-handlers from a DOM element. Each event handler attached by
[addEventListener](#addeventlistenernode-eventns-listener) is tracked by an
internal store, which keeps track of the event type and the namespace linked
to a DOM Element.
[addEventListener](#addeventlistenernode-eventns-listener-capture) is tracked
by an internal store, which keeps track of the event type and the namespace
linked to a DOM Element.

It receives the following arguments:

Expand All @@ -204,7 +244,7 @@ var title = document.getElementById('title');

jsu.getEventListeners(title); // get all event listeners
jsu.getEventListeners(title, 'click'); // get all listeners by event
jsu.getEventListeners(title, '.tooltip'); // get all listeners by namespace
jsu.getEventListeners(title, '.tooltip'); // get all listeners by namespace
jsu.getEventListeners(title, 'mouseover.tooltip'); // get listeners by event + namespace
```

Expand Down Expand Up @@ -243,18 +283,18 @@ handleEvents(node: Element) : Object
```

This _factory-method_ is a _facade_ that simplifies the tasks for
[attaching](#addeventlistenernode-eventns-listener) and
[attaching](#addeventlistenernode-eventns-listener-capture) and
[removing](#removeeventlistenernode-eventns-listener) event listeners.
It implements a _fluent interface_ that allows the chaining of methods
(as jQuery does). It receives an argument that is the DOM `Element` to
which you will attach or remove event-handlers.

The methods exposed are:

- **on** `Function`: facade of [addEventListener](#addeventlistenernode-eventns-listener).
It only receives two arguments: `(eventns, listener)`
- **off** `Function`: facade of [removeEventListener](#removeeventlistenernode-eventns-listener).
It only receives two arguments: `(eventns, listener)`
- **on()** `Function`: facade of [addEventListener](#addeventlistenernode-eventns-listener-capture).
It receives the following arguments: `(eventns, listener, capture)`
- **off()** `Function`: facade of [removeEventListener](#removeeventlistenernode-eventns-listener).
It receives the following arguments: `(eventns, listener)`

```javascript
const evtHandler = (e) => console.log(`triggered ${e.type}`);
Expand Down
30 changes: 19 additions & 11 deletions dist/handle-events.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*! handle-events@v1.0.0a. Jherax 2017. Visit https://github.com/jherax/handle-events */
/*! handle-events@v1.1.0. Jherax 2017. Visit https://github.com/jherax/handle-events */
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
Expand Down Expand Up @@ -110,7 +110,7 @@ var NODES = [];
* @param {Element} node: DOM element
* @param {String} eventns: name of the event/namespace to register
* @param {Function} listener: event handler
* @param {Boolean} useCapture: Event Capture
* @param {Boolean} useCapture: event capture
*/
function addEventListener(node, eventns, listener) {
var useCapture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
Expand Down Expand Up @@ -146,7 +146,6 @@ function addEventListener(node, eventns, listener) {
* Removes an event-handler from a DOM element.
* Events with namespace are allowed.
*
* @private
* @param {Element} node: DOM element
* @param {String} eventns: (optional) name of the event/namespace to remove
* @param {Function} listener: (optional) event handler
Expand Down Expand Up @@ -230,13 +229,16 @@ function getEventListeners(node, eventns) {
}

/**
* Attaches a listener to a DOM `Element` but delegates the event-listener
* to the DOM Elements beneath that matches with the `selector` provided.
*
* @param {Element} node: DOM element
* @param {String} selector: CSS Selector for the event
* @param {String} eventns: name of the event/namespace to register
* @param {String} selector: CSS selector for those elements that will propagate the event
* @param {Function} listener: event handler
* @param {Boolean} useCapture: Event Capture
* @param {Boolean} useCapture: event capture
*/
function delegate(node, selector, eventns, listener, useCapture) {
function delegate(node, eventns, selector, listener, useCapture) {
addEventListener(node, eventns, function (e) {
if (e.target.matches(selector)) {
listener(e);
Expand Down Expand Up @@ -285,6 +287,10 @@ module.exports = exports['default'];
"use strict";


/**
* https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
*/

if (typeof Element !== 'undefined' && !Element.prototype.matches) {
var proto = Element.prototype;

Expand Down Expand Up @@ -319,7 +325,9 @@ function handleEvents(node) {
return fluent;
};
fluent.on = function (eventns, listener) {
(0, _events.addEventListener)(node, eventns, listener);
var useCapture = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;

(0, _events.addEventListener)(node, eventns, listener, useCapture);
return fluent;
};
return fluent;
Expand All @@ -344,13 +352,13 @@ exports.detachEvent = detachEvent;
* @param {Element} node: DOM element
* @param {String} eventName: name of the event to register
* @param {Function} listener: event handler
* @param {Boolean} useCapture: Event Capture
* @param {Boolean} useCapture: event capture
*/
function attachEvent(node, eventName, listener) {
var useCapture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;

if (node.addEventListener) {
node.addEventListener(eventName, listener, useCapture);
node.addEventListener(eventName, listener, !!useCapture);
} else {
node.attachEvent("on" + eventName, listener);
}
Expand All @@ -362,13 +370,13 @@ function attachEvent(node, eventName, listener) {
* @param {Element} node: DOM element
* @param {String} eventName: name of the event to register
* @param {Function} listener: event handler
* @param {Boolean} useCapture: Event Capture
* @param {Boolean} useCapture: event capture
*/
function detachEvent(node, eventName, listener) {
var useCapture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;

if (node.removeEventListener) {
node.removeEventListener(eventName, listener, useCapture);
node.removeEventListener(eventName, listener, !!useCapture);
} else {
node.detachEvent("on" + eventName, listener);
}
Expand Down
Loading

0 comments on commit 82d6954

Please sign in to comment.