Skip to content

Instantly share code, notes, and snippets.

@motionharvest
Created May 8, 2015 21:03
Show Gist options
  • Save motionharvest/9e6808dee7810b5ff036 to your computer and use it in GitHub Desktop.
Save motionharvest/9e6808dee7810b5ff036 to your computer and use it in GitHub Desktop.
Toggles And Switches
/**
* Toggles & Switches
* ------------------
*/
(function() {
"use strict";
// switch constructor
function Switch(opts) {
this.type = opts.type;
this.element = opts.element;
this.target = document.querySelectorAll(opts.target);
this.event = opts.event || 'click';
this.className = opts.class || 'active';
this.add = opts.add || false;
this.remove = opts.remove || false;
this.self = opts.self || false;
this.stopPropagation = opts.stopPropagation || false;
if(!this.target) {
return false;
}
// set up switch event listeners
_bindEventListeners.apply(this);
}
// toggle constructor
function Toggle(opts) {
this.element = opts.element;
this.target = document.querySelectorAll(opts.target);
this.className = opts.class || 'active';
this.event = opts.event || 'click';
this.self = opts.self || false;
this.stopPropagation = opts.stopPropagation || false;
if(!this.target) {
return false;
}
// set up toggle event listeners
_bindEventListeners.apply(this);
}
// set up single or multiple event listeners
function _bindEventListeners() {
var events = this.event.split(',');
// will be array of length 1 if single event
events.forEach(function(event) {
_bindEventListener.apply(this, [event]);
}.bind(this));
}
// bind a single event listener
function _bindEventListener(event) {
this.element.addEventListener(event, function(e) {
e.preventDefault();
if(this.stopPropagation) {
e.stopPropagation();
}
this.fire();
}.bind(this));
}
// add class of className to target
function _addClass() {
[].forEach.call(this.target, function(el) {
el.classList.add(this.className);
}.bind(this));
if(this.self) {
this.element.classList.add(this.className);
}
}
// remove class of className from target
function _removeClass() {
[].forEach.call(this.target, function(el) {
el.classList.remove(this.className);
}.bind(this));
if(this.self) {
this.element.classList.remove(this.className);
}
}
// toggle class of className on target
function _toggleClass() {
[].forEach.call(this.target, function(el) {
el.classList.toggle(this.className);
}.bind(this));
if(this.self) {
this.element.classList.toggle(this.className);
}
}
// replace remove class with add class
function _replaceClass() {
[].forEach.call(this.target, function(el) {
el.classList.remove(this.remove);
el.classList.add(this.add);
}.bind(this));
}
// fire switch
Switch.prototype.fire = function() {
// this is a replace switch so replace
if(this.type === 'replace') {
_replaceClass.apply(this);
// class not applied this is an on switch so add
} else if(this.type === 'on') {
_addClass.apply(this);
// class applied this is an off switch so remove
} else if(this.type === 'off') {
_removeClass.apply(this);
}
};
// fire toggle
Toggle.prototype.fire = function() {
_toggleClass.apply(this);
};
/**
* Data-Attr API
* -------------
*
* <a href="#" data-toggle=".something"
* data-toggle-classname="toggled">
* Toggle
* </a>
*
* <a href="#" data-switch=".something"
* data-switch-classname="switched">
* Switch
* </a>
*
* <a href="#" data-switch-replace=".something"
* data-switch-add="add"
* data-switch-remove="remove">
* Switch
* </a>
*/
var toggles = document.querySelectorAll('[data-toggle]'),
switchesOn = document.querySelectorAll('[data-switch-on]'),
switchesOff = document.querySelectorAll('[data-switch-off]'),
switchesReplace = document.querySelectorAll('[data-switch-replace]');
// set up toggles
[].forEach.call(toggles, function(t) {
// required params
var opts = {
element: t,
target: t.getAttribute('data-toggle')
};
// optional params
if(t.hasAttribute('data-toggle-class')) {
opts.class = t.getAttribute('data-toggle-class');
}
if(t.hasAttribute('data-toggle-event')) {
opts.event = t.getAttribute('data-toggle-event');
}
if(t.hasAttribute('data-toggle-self')) {
opts.self = true;
}
if(t.hasAttribute('data-toggle-stop-propagation')) {
opts.stopPropagation = true;
}
new Toggle(opts);
});
// set up on switches
[].forEach.call(switchesOn, function(s) {
// required params
var opts = {
type: 'on',
element: s,
target: s.getAttribute('data-switch-on')
};
// optional params
if(s.hasAttribute('data-switch-class')) {
opts.class = s.getAttribute('data-switch-class');
}
if(s.hasAttribute('data-switch-event')) {
opts.event = s.getAttribute('data-switch-event');
}
if(s.hasAttribute('data-switch-self')) {
opts.self = true;
}
if(s.hasAttribute('data-switch-stop-propagation')) {
opts.stopPropagation = true;
}
new Switch(opts);
});
// set up off switches
[].forEach.call(switchesOff, function(s) {
// required params
var opts = {
type: 'off',
element: s,
target: s.getAttribute('data-switch-off')
};
// optional params
if(s.hasAttribute('data-switch-class')) {
opts.class = s.getAttribute('data-switch-class');
}
if(s.hasAttribute('data-switch-event')) {
opts.event = s.getAttribute('data-switch-event');
}
if(s.hasAttribute('data-switch-self')) {
opts.self = true;
}
if(s.hasAttribute('data-switch-stop-propagation')) {
opts.stopPropagation = true;
}
new Switch(opts);
});
// set up replace switches
[].forEach.call(switchesReplace, function(s) {
// required params
var opts = {
type: 'replace',
element: s,
target: s.getAttribute('data-switch-replace'),
add: s.getAttribute('data-switch-add'),
remove: s.getAttribute('data-switch-remove')
};
new Switch(opts);
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment