Organizing functionality
Daisho Komiyama edited this page Jul 5, 2018
·
2 revisions
They say being able to organize functions is one of necessary skillsets for JS dev who has two to three years of experience. Agreed.
*Task 1, 2 and 4 are omitted; See repo: Module_Pattern_Example
Refactor "header.js", "carousel.js", and "details.js" to use the "module pattern". Each file should expose one module name (Header, Carousel, and Details, respectively).
var $modal = $("[rel=js-modal]");
$("[rel=js-header]").on("click","> [rel^=js]",function(evt){
evt.preventDefault();
evt.stopPropagation();
evt.stopImmediatePropagation();
var url = $(evt.target).attr("href");
$.ajax(url,{ dataType: "text" })
.then(function(contents){
$modal.html(contents).show();
});
});
var Header = (function() {
function clickHeaderLink(event) {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
var url = $(event.target).attr("href");
$.ajax(url,{ dataType: "text" })
.then(function(contents){
$modal.html(contents).show();
});
}
function init() {
$modal = $("[rel=js-modal]");
$("[rel=js-header]").on("click","> [rel^=js]", clickHeaderLink);
}
var $modal;
return {
init: init
};
})();
$(document).ready(function(){
function scrollLeft(evt) {
evt.preventDefault();
evt.stopPropagation();
evt.stopImmediatePropagation();
if (position > 0) {
position = Math.max(0,position - 250);
}
$items.css({ left: (-position) + "px" });
}
function scrollRight(evt){
evt.preventDefault();
evt.stopPropagation();
evt.stopImmediatePropagation();
if (position < maxPosition) {
position = Math.min(maxPosition,position + 250);
}
$items.css({ left: (-position) + "px" });
}
var $content = $("[rel=js-carousel] > [rel=js-content]");
var $items = $content.children("[rel=js-items]");
var $left = $("[rel=js-carousel] > [rel=js-controls] > [rel=js-left]");
var $right = $("[rel=js-carousel] > [rel=js-controls] > [rel=js-right]");
var contentWidth = $content.width();
var itemsWidth = $items.width();
var position = 0;
var maxPosition = (itemsWidth - contentWidth);
$left.click(scrollLeft);
$right.click(scrollRight);
});
var Carousel = (function() {
function scrollLeft(evt) {
evt.preventDefault();
evt.stopPropagation();
evt.stopImmediatePropagation();
if (position > 0) {
position = Math.max(0,position - 250);
}
$items.css({ left: (-position) + "px" });
}
function scrollRight(evt){
evt.preventDefault();
evt.stopPropagation();
evt.stopImmediatePropagation();
if (position < maxPosition) {
position = Math.min(maxPosition,position + 250);
}
$items.css({ left: (-position) + "px" });
}
function personClicked(event) {
event.preventDefault();
var ID = $(event.target).attr('rel').replace(/^.*(\d+)$/, '$1');
Details.loadPerson(ID);
}
function init() {
$content = $("[rel=js-carousel] > [rel=js-content]");
$items = $("[rel=js-carousel] > [rel=js-content] > [rel=js-items]");
$left = $("[rel=js-carousel] > [rel=js-controls] > [rel=js-left]");
$right = $("[rel=js-carousel] > [rel=js-controls] > [rel=js-right]");
$items.on('click', '> [rel^="js-item-"]', personClicked);
contentWidth = $content.width();
itemsWidth = $items.width();
position = 0;
maxPosition = (itemsWidth - contentWidth);
$left.on('click', scrollLeft);
$right.on('click', scrollRight);
}
var $content, $items, $left, $right,
contentWidth, itemsWidth, position, maxPosition
;
//Publish init,
//other than that, nothing is accessible so that you can keep global name space clean
return {
init: init
};
})();
$(document).ready(function(){
var $items = $("[rel=js-carousel] > [rel=js-content] > [rel=js-items]");
var $content = $("[rel=js-details]");
function loadPerson(ID) {
$.ajax("details/" + ID + ".html",{ dataType: "text" })
.then(function(content){
$content.html(content);
});
}
function personClicked(evt) {
evt.preventDefault();
evt.stopPropagation();
evt.stopImmediatePropagation();
var ID = $(evt.target).attr("rel").replace(/^.*(\d+)$/,"$1");
loadPerson(ID);
}
$items.on("click","> [rel^=js-item-]",personClicked);
});
var Details = (function() {
function loadPerson(ID) {
$.ajax('details/' + ID + '.html', {
dataType: 'text'
}).then(function(content) {
$('[rel="js-details"]').html(content);
});
}
function init() {
$content = $("[rel=js-details]");
}
var $content;
//Publish only two functions below,
//other than those, nothing is accessible so that you can keep global name space clean
return {
init: init,
loadPerson: loadPerson
};
})();
$(document).ready(function() {
Header.init();
Carousel.init();
Details.init();
});
...
<script src="js/header.js"></script>
<script src="js/carousel.js"></script>
<script src="js/details.js"></script>
<script src="js/app.js"></script>
...