Skip to content

Instantly share code, notes, and snippets.

@sokcuri
Created July 17, 2017 07:52
Show Gist options
  • Save sokcuri/c047c3ffb4c414eea9bb487d020bdf51 to your computer and use it in GitHub Desktop.
Save sokcuri/c047c3ffb4c414eea9bb487d020bdf51 to your computer and use it in GitHub Desktop.
const Template = {
NavigateTab: `<div class="badge">{{clickCount}}</div><div class="content" id="{{id}}"><span>{{text}}</span></div>`,
Section: `<div class="pageHeader"><h3>{{title}}</h3></div><p>{{content}}</p>`
}
const TabInfo = [
{
id: 'position',
text: 'About me'
},
{
id: 'news',
text: 'News'
},
{
id: 'following',
text: 'Following'
},
{
id: 'follower',
text: 'Follower'
},
{
id: 'comment',
text: 'Comment'
}
]
class TabList extends Array {
constructor() {
super([]);
}
init(TabInfo) {
let num = 0;
TabInfo.forEach(tab => this.push(new Tab(tab.id, tab.text, num++ === 0)));
}
push(tabObject) {
document.querySelector('.tabArea').appendChild(tabObject.makeNode());
super.push(tabObject);
}
}
class Tab {
constructor(id, text, firstTab) {
this.data = this.initData.apply(this, arguments);
this.createSection(firstTab);
this.registerEvents();
}
initData(id, text, clickCount) {
return {
id: id,
text: text,
clickCount: 0
}
}
createSection(selected) {
this.node = document.createElement('section');
this.node.classList.add('tab');
if (selected) {
this.data.clickCount++;
this.node.classList.add('selectedTab');
}
}
registerEvents() {
this.node.addEventListener('click', this.clickCountHandler.bind(this));
}
clickCountHandler() {
this.data.clickCount++;
this.makeNode();
}
getData() {
return this.data;
}
makeNode() {
this.node.innerHTML = Handlebars.compile(Template.NavigateTab)(this.getData());
return this.node;
}
}
class Navigator {
constructor() { }
init() {
this.registerEvents();
this.clickTabDelegate({target: document.querySelector('nav > section')});
}
registerEvents() {
document.querySelector('nav').addEventListener('click', this.clickTabDelegate.bind(this));
}
switchElement(element, name) {
let prev_el = document.querySelector(`.${name}`);
if (prev_el)
prev_el.classList.remove(name);
element.classList.add(name);
}
clickTabDelegate(evt) {
let tabElement = evt.target;
let id = evt.target.querySelector('.content').id;
let sectionElement = document.querySelector(`.sectionArea .${id}`) || this.createTabSection(id);
this.switchElement(tabElement, 'selectedTab');
this.switchElement(sectionElement, 'eleDisplayShow');
if (!sectionElement.dataset.receivedData) {
sectionElement.dataset.receivedData = true;
let reqURL = (document.location.href.indexOf('file:') === 0) ? 'http:' : '';
reqURL += '//jsonplaceholder.typicode.com/posts/' + this.getTabNumber(tabElement);
let updateSection = this.updateSection;
xhr.get(reqURL, function() {
updateSection(sectionElement, JSON.parse(this.responseText));
});
}
}
createTabSection(id) {
let sectionArea = document.querySelector('.sectionArea');
let sectionElement = document.createElement('div');
sectionElement.classList.add(id);
sectionArea.appendChild(sectionElement);
return sectionElement;
}
getTabNumber(element) {
let navTabs = Array.from(document.querySelectorAll('nav > .tab'));
for (let i = 0; i < navTabs.length; i++) {
if (navTabs[i] == element)
return i + 1;
}
}
updateSection(sectionElement, obj) {
let result = Handlebars.compile(Template.Section)({title: obj.title, content: obj.body});
sectionElement.innerHTML = result;
}
}
class Xhr {
constructor() {
this.xhr = new XMLHttpRequest();
}
send(url, methods, callback) {
this.xhr.addEventListener('load', callback);
this.xhr.open(methods, url);
this.xhr.send();
}
get(url, callback) {
this.send(url, 'get', callback);
}
post(url, callback) {
this.send(url, 'post', callback);
}
}
const xhr = new Xhr();
const tabList = new TabList();
const nav = new Navigator();
document.addEventListener('DOMContentLoaded', function () {
tabList.init(TabInfo);
nav.init();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment