tui-code-snippet
Version:
TOAST UI Utility: CodeSnippet
115 lines (100 loc) • 3.19 kB
JavaScript
/**
* @fileoverview Bind DOM events
* @author NHN FE Development Lab <dl_javascript@nhn.com>
*/
;
var isString = require('../type/isString');
var forEach = require('../collection/forEach');
var safeEvent = require('./_safeEvent');
/**
* Bind DOM events.
* @param {HTMLElement} element - element to bind events
* @param {(string|object)} types - Space splitted events names or eventName:handler object
* @param {(function|object)} handler - handler function or context for handler method
* @param {object} [context] context - context for handler method.
* @memberof module:domEvent
* @example
* const div = document.querySelector('div');
*
* // Bind one event to an element.
* on(div, 'click', toggle);
*
* // Bind multiple events with a same handler to multiple elements at once.
* // Use event names splitted by a space.
* on(div, 'mouseenter mouseleave', changeColor);
*
* // Bind multiple events with different handlers to an element at once.
* // Use an object which of key is an event name and value is a handler function.
* on(div, {
* keydown: highlight,
* keyup: dehighlight
* });
*
* // Set a context for handler method.
* const name = 'global';
* const repository = {name: 'CodeSnippet'};
* on(div, 'drag', function() {
* console.log(this.name);
* }, repository);
* // Result when you drag a div: "CodeSnippet"
*/
function on(element, types, handler, context) {
if (isString(types)) {
forEach(types.split(/\s+/g), function(type) {
bindEvent(element, type, handler, context);
});
return;
}
forEach(types, function(func, type) {
bindEvent(element, type, func, handler);
});
}
/**
* Bind DOM events
* @param {HTMLElement} element - element to bind events
* @param {string} type - events name
* @param {function} handler - handler function or context for handler method
* @param {object} [context] context - context for handler method.
* @private
*/
function bindEvent(element, type, handler, context) {
/**
* Event handler
* @param {Event} e - event object
*/
function eventHandler(e) {
handler.call(context || element, e || window.event);
}
if ('addEventListener' in element) {
element.addEventListener(type, eventHandler);
} else if ('attachEvent' in element) {
element.attachEvent('on' + type, eventHandler);
}
memorizeHandler(element, type, handler, eventHandler);
}
/**
* Memorize DOM event handler for unbinding.
* @param {HTMLElement} element - element to bind events
* @param {string} type - events name
* @param {function} handler - handler function that user passed at on() use
* @param {function} wrappedHandler - handler function that wrapped by domevent for implementing some features
* @private
*/
function memorizeHandler(element, type, handler, wrappedHandler) {
var events = safeEvent(element, type);
var existInEvents = false;
forEach(events, function(obj) {
if (obj.handler === handler) {
existInEvents = true;
return false;
}
return true;
});
if (!existInEvents) {
events.push({
handler: handler,
wrappedHandler: wrappedHandler
});
}
}
module.exports = on;