Skip to content

Instantly share code, notes, and snippets.

@pfraces
Last active August 29, 2015 14:02
Show Gist options
  • Save pfraces/96fd3eb3361265c7bc28 to your computer and use it in GitHub Desktop.
Save pfraces/96fd3eb3361265c7bc28 to your computer and use it in GitHub Desktop.
dom.js - a DOM selector with plugins
// straightforward implementation
//
// drawbacks:
//
// - using querySelectorAll always returns an array, when the main use case is to select just one,
// having to access to the first node: dom('#nodeId')[0]
//
// - using querySelector just return the first element so we need an alternative way of access the
// other possible nodes
//
// - it does not support plugins
define('dom', function () {
return document.querySelectorAll.bind(document);
});
// solves the querySelectorX dilemma by providing a cps api
// which may cause pyramid of doom issues
//
// it does not support plugins
define('dom', function () {
var dom = function (selector, callback) {
var nodeList = document.querySelectorAll(selector),
nodes = [].slice.call(nodeList);
nodes.forEach(callback);
};
return dom;
});
// solves the querySelectorX dilemma by providing a cps api
// which causes pyramid of doom issues
//
// the plugin pattern implemented using partial application
// allows for plugin reuse
//
// plugins could be defined with a plugn definition object
define('dom', function () {
var plugins = {};
var addPlugin = function (name, plugin) {
plugins[name] = plugin;
};
var createPlugged = function (node) {
var plugged = {};
Object.keys(plugins).forEach(function (name) {
plugged[name] = plugins[name].bind(null, node);
});
return plugged;
};
var dom = function (selector, callback) {
var nodeList = document.querySelectorAll(selector),
nodes = [].slice.call(nodeList);
nodes.forEach(function (node) {
callback(createPlugged(node));
});
};
dom.plugin = addPlugin;
return dom;
});
define('dom.raw', function () {
return function (node) { return node; };
});
define('dom.on', function () {
var on = function (node, event, handler) {
return node.addEventListener(event, handler);
};
return on;
});
// usage
define('app.dom', function (require) {
var dom = require('dom');
// TODO
//
// dom.plugin({
// raw: require('dom.raw'),
// on: require('dom.on')
// });
dom.plugin('raw', require('dom.raw'));
dom.plugin('on', require('dom.on'));
return dom;
});
define.root(function (require) {
var dom = require('app.dom');
dom('body', function (node) {
node.raw().style.backgroundColor = 'red';
});
dom('body', function (node) {
node.raw().innerHTML = '<h1>Click me!</h1>';
});
// TODO
//
// dom('h1').on('click', function () {
// dom('body').raw(function (node) {
// node.style.backgroundColor = 'blue';
// });
// });
dom('h1', function (node) {
node.on('click', function () {
dom('body', function (node) {
node.raw().style.backgroundColor = 'blue';
});
});
});
});
@pfraces
Copy link
Author

pfraces commented Jun 14, 2014

story continues at http://plnkr.co/edit/ln64qt?p=preview
story was successfully wrapped in a library: https://github.com/domojs/domo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment