Last active
November 5, 2015 16:54
-
-
Save roccomuso/9422b02451462df176fc to your computer and use it in GitHub Desktop.
Modular Javascript - How to create javascript modules and use event handling. Inspired by: https://www.youtube.com/playlist?list=PLoYCgNOIyGABs-wDaaxChu82q_xQgUb4f
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>Modules in JS</title> | |
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> | |
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.1.3/mustache.min.js"></script> | |
<link rel="stylesheet" type="text/css" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> | |
<link rel="stylesheet" type="text/css" href="./style.css"> | |
</head> | |
<body> | |
<div class="hero-unit" id="statsModule"></div> | |
<script id="stats-template" type="text/template"> | |
<h2>Stats</h2> | |
<strong>people: {{people}}</strong> | |
</script> | |
<div id="peopleModule"> | |
<h1>People</h1> | |
<input placeholder="name" type="text"> | |
<button id="addPerson">Add Person</button> | |
<ul id="people"> | |
<script id="people-template" type="text/template"> | |
{{#people}} | |
<li> | |
<span>{{.}}</span> | |
<i class="del">X</i> | |
</li> | |
{{/people}} | |
</script> | |
</ul> | |
</div> | |
</body> | |
<script type="text/javascript" src="./modules.js"></script> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//events (publish subscribe) pattern [aka Event Emitter] | |
var events = { | |
events: {}, | |
on: function (eventName, fn) { | |
this.events[eventName] = this.events[eventName] || []; | |
this.events[eventName].push(fn); | |
}, | |
off: function(eventName, fn) { | |
if (this.events[eventName]) { | |
for (var i = 0; i < this.events[eventName].length; i++) { | |
if (this.events[eventName][i] === fn) { | |
this.events[eventName].splice(i, 1); | |
break; | |
} | |
}; | |
} | |
}, | |
emit: function (eventName, data) { | |
if (this.events[eventName]) { | |
this.events[eventName].forEach(function(fn) { | |
fn(data); | |
}); | |
} | |
} | |
}; | |
// Stats module | |
(function(){ | |
var people = 0; | |
//cache DOM | |
var $stats = $('#statsModule'); | |
var template = $('#stats-template').html(); | |
//bind events | |
events.on('peopleChanged', setPeople); | |
_render(); | |
function _render() { | |
$stats.html(Mustache.render(template, {people: people})); | |
} | |
function setPeople(newPeople) { | |
people = newPeople; | |
_render(); | |
} | |
})(); | |
// People module (exposes some API) | |
var people = (function(){ | |
var people = ['Will', 'Steve']; | |
//cache DOM | |
var $el = $('#peopleModule'); | |
var $button = $el.find('button'); | |
var $input = $el.find('input'); | |
var $ul = $el.find('ul'); | |
var template = $el.find('#people-template').html(); | |
//bind events | |
$button.on('click', addPerson); | |
$ul.delegate('i.del', 'click', deletePerson); | |
_render(); | |
function _render() { | |
$ul.html(Mustache.render(template, {people: people})); | |
events.emit("peopleChanged", people.length); | |
} | |
function addPerson(value) { | |
var name = (typeof value === "string") ? value : $input.val(); | |
people.push(name); | |
_render(); | |
$input.val(''); | |
} | |
function deletePerson(event) { | |
var i; | |
if (typeof event === "number") { | |
i = event; | |
} else { | |
var $remove = $(event.target).closest('li'); | |
i = $ul.find('li').index($remove); | |
} | |
people.splice(i, 1); | |
_render(); | |
} | |
// (API) methods we would like to expose | |
return { | |
addPerson: addPerson, | |
aggiungiPersona: addPerson | |
}; | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
background: #fafafa; | |
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
color: #333; | |
} | |
.hero-unit { | |
margin: 20px auto 0 auto; | |
width: 300px; | |
font-size: 12px; | |
font-weight: 200; | |
line-height: 20px; | |
background-color: #eee; | |
border-radius: 6px; | |
padding: 10px 20px; | |
} | |
.hero-unit h1 { | |
font-size: 60px; | |
line-height: 1; | |
letter-spacing: -1px; | |
} | |
.browsehappy { | |
margin: 0.2em 0; | |
background: #ccc; | |
color: #000; | |
padding: 0.2em 0; | |
} | |
input { | |
border: 1px solid #999; | |
border-radius: 4px; | |
padding: 10px; | |
} | |
button { | |
zoom: 2; | |
background-color: #999; | |
border: 1px solid #999; | |
border-radius: 4px; | |
padding: 1px 5px; | |
} | |
button.active { | |
background-color:rgb(165, 227, 158); | |
} | |
#peopleModule { | |
text-align: center; | |
} | |
#peopleModule ul { | |
padding: 0; | |
} | |
#peopleModule li { | |
display: inline-block; | |
list-style-type: none; | |
background: #98ec9b; | |
border-radius: 5px; | |
padding: 3px 8px; | |
margin: 5px 0; | |
width: 200px; | |
opacity: 0.8; | |
transition: opacity 0.3s; | |
} | |
#peopleModule li:hover { | |
opacity: 1; | |
} | |
#peopleModule li span { | |
display: inline-block; | |
width: 160px; | |
overflow: hidden; | |
text-overflow: ellipsis; | |
} | |
#peopleModule li i { | |
cursor: pointer; | |
font-weight: bold; | |
float: right; | |
font-style: normal; | |
background: #666; | |
padding: 2px 4px; | |
font-size: 60%; | |
color: white; | |
border-radius: 20px; | |
opacity: 0.7; | |
transition: opacity 0.3s; | |
margin-top: 3px; | |
} | |
#peopleModule li i:hover { | |
opacity: 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment