Created
July 12, 2017 12:03
-
-
Save sokcuri/7e8e224647478d78b0076f027b6a6f3f to your computer and use it in GitHub Desktop.
This file contains hidden or 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과 CSS를 수정하지 않고 기능추가. | |
// * 코드를 더 개선해 볼 것 * | |
// √ 1. Switch, if 등 조건에 해당하는 것을 최대한 줄일 것 | |
// √ 2. event delegation을 잘 써서 for문으로 돌렸던 addEventListener를 삭제 | |
// √ 3. AJAX 재요청 없게끔 만들기 | |
// DOMContentLoaded가 호출되면 하는 일 | |
// 1) 이벤트를 등록한다 | |
// - 'nav' 태그에 'click' 이벤트를 등록한다 | |
// 2) 첫번째 탭의 내용을 서버에서 불러온다 | |
// 3) CSS를 삽입한다 | |
// pointer-events: none; 을 넣은 이유는 클릭했을 때 tab 하위의 element가 클릭되는걸 막기 위함 | |
document.addEventListener('DOMContentLoaded', function () { | |
registerEvents(); | |
loadContents(); | |
insertCSS('.tab * { pointer-events: none; }'); | |
}); | |
// CSS를 인라인으로 삽입해주는 함수 | |
function insertCSS(css) { | |
if (!checkParam(arguments, 1)) | |
return false; | |
var styleElem = document.createElement('style'); | |
styleElem.type = 'text/css'; | |
(styleElem.styleSheet) ? | |
styleElem.styleSheet.cssText = css : | |
styleElem.appendChild(document.createTextNode(css)); | |
document.getElementsByTagName('head')[0].appendChild(styleElem); | |
} | |
function registerEvents() { | |
setHandlerTab(); | |
} | |
function loadContents() { | |
let el = document.querySelectorAll('nav > *')[0]; | |
setContent(el, el.id); | |
} | |
function setHandlerTab() { | |
const nav = getNav(); | |
nav.addEventListener('click', tabClickDelegate); | |
} | |
function tabClickDelegate(evt) { | |
// evt.target이 nav면 클릭한게 아니라 드래그한 경우 | |
if (evt.target == this) return; | |
// 클릭한 탭에 색이 들어가고 탭에 해당하는 섹션이 보이도록 조정 | |
let tabElement = evt.target; | |
let sectionElement = document.querySelector(`#my_${evt.target.id}`); | |
visibleTab(tabElement); | |
visibleSection(sectionElement); | |
// 탭에 컨텐츠를 채워넣는다 | |
setContent(tabElement); | |
} | |
function visibleTab(el) { | |
return visibleControl(el, 'selectedTab'); | |
} | |
function visibleSection(el) { | |
return visibleControl(el, 'eleDisplayShow'); | |
} | |
function visibleControl(el, name) { | |
if (!checkParam(arguments, 2)) | |
return false; | |
el.parentNode.getElementsByClassName(name)[0].classList.remove(name); | |
el.classList.add(name); | |
} | |
// nav 태그 element를 가져온다 | |
function getNav() { | |
return document.querySelector('nav'); | |
} | |
// nav element 안의 tab 이름을 가진 div들을 가져온다 | |
function getNavTabs() { | |
return Array.from(document.querySelectorAll('nav > div.tab')); | |
} | |
function getJsonURL(number = 1) { | |
return `http://jsonplaceholder.typicode.com/posts/${number}`; | |
} | |
function getTabNumber(tabElement) { | |
const navTabs = getNavTabs(); | |
for (let i = 0; i < navTabs.length; i++) { | |
if (navTabs[i] == tabElement) | |
return i + 1; | |
} | |
} | |
// 탭을 클릭했을 때 이 함수가 호출됨. | |
// 서버에서 한번도 가져온 적이 없을 때 JSON을 가져오기 | |
function setContent(el) { | |
let id = el.id; | |
let number = getTabNumber(el); | |
if (!el.classList.contains('receivedData')) { | |
console.log(`[get] number: ${number}, id: ${id}`); | |
el.classList.add('receivedData'); | |
// () => 화살표 함수를 쓰면 this를 못가져온다 | |
reqContents(getJsonURL(number), function() { | |
return updateSection(`#my_${id}`, JSON.parse(this.responseText)); | |
}); | |
} | |
} | |
// 컨텐츠를 요청. XHR | |
function reqContents(url, callback) { | |
if (!checkParam(arguments, 2)) | |
return false; | |
let oReq = new XMLHttpRequest(); | |
oReq.addEventListener('load', callback); | |
oReq.open('GET', url); | |
oReq.send(); | |
} | |
// 섹션을 업데이트 | |
function updateSection(el_id, obj) { | |
if (!checkParam(arguments, 2)) | |
return false; | |
let template = "<ul > <li > <div class='myName' ><%=title%></div> <div class='myDesc' ><%=body%></div> </li> </ul>"; | |
let result = _.template(template)({title: obj.title, body: obj.body}); | |
document.querySelector(el_id).innerHTML = result; | |
} | |
// 파라메터가 유효한지 확인한다 | |
function checkParam(func_arg, len) { | |
let numbers = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten']; | |
if (func_arg.length < len) { | |
console.error(`${func_arg.callee.name} must requires ${numbers[len]} parameter${(len > 1) ? 's.' : '.'}`); | |
return false; | |
} | |
return true; | |
} |
This file contains hidden or 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
header,nav,section,div,footer,ul,dd {margin:0;padding:0;} | |
li{list-style: none;} | |
dt { | |
font-weight: bold; | |
font-size: 1.2em; | |
margin-bottom: 5px; | |
} | |
dl { | |
float: left; | |
width : 75%; | |
} | |
dd { | |
font-size: 0.9em; | |
} | |
.mainHeader{ | |
height:200px; | |
text-align: center; | |
padding-top: 20px; | |
line-height: 1.4em | |
} | |
.userId { | |
font-size: 1.2em; | |
font-weight: bold; | |
} | |
.userMessage, .userSNSInfo { | |
font-size: 0.8em; | |
color : gray; | |
} | |
.userSNSInfo { | |
overflow: auto; | |
width: 255px; | |
margin: 0px auto; | |
} | |
.userSNSInfo > li { | |
float: left; | |
margin-right: 5px; | |
width : 80px; | |
} | |
.userSNSInfo span.count { | |
color : #1FB820; | |
} | |
.mainView > nav { | |
height:40px; | |
margin-top: 10px; | |
overflow: auto; | |
border-bottom: 1px solid rgb(228, 228, 228); | |
border-top: 1px solid rgb(228, 228, 228); | |
} | |
.tab { | |
border-right: 1px solid rgb(228, 228, 228); | |
float:left; | |
height:100%; | |
line-height: 40px; | |
text-align: center; | |
width:24.5%; | |
cursor: pointer; | |
} | |
.tab:last-child { | |
border-right: 0px; | |
} | |
.mainView > section { | |
display:none; | |
padding:8%; | |
line-height: 1.5em; | |
} | |
.mainView > section.eleDisplayShow { | |
display:block; | |
padding:8%; | |
line-height: 1.5em; | |
} | |
.myName { | |
font-size: 1.2em; | |
font-weight: bold; | |
} | |
.myDesc { | |
font-size: 0.8em; | |
} | |
.eleDisplayShow li { | |
margin-bottom: 8%; | |
} | |
.selectedTab { | |
background-color: #DF9274; | |
color: #fff; | |
} |
This file contains hidden or 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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, user-scalable=no"> | |
<title>tabUI</title> | |
<link rel="stylesheet" href="tabUI.css"> | |
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script> | |
<script src=./script.js></script> | |
</head> | |
<body> | |
<div id="wrapper"> | |
<div class="mainView" > | |
<header class="mainHeader" ><img src="https://avatars1.githubusercontent.com/u/1456761?v=3&s=140" width="80" > | |
<div class="userId" ><span > </span><span >nigayo</span><span > </span> | |
</div> | |
<div class="userMessage" ><span > </span><span >안녕하세요 nigayo입니다.</span><span > </span> | |
</div> | |
<ul class="userSNSInfo" > | |
<li ><span >review : </span><span class="count" >10</span><span > | </span> | |
</li> | |
<li ><span >follower : </span><span class="count" ><span >12</span><span > </span></span><span > | </span> | |
</li> | |
<li ><span >following : </span><span class="count" ><span >30</span><span > </span></span><span > </span> | |
</li> | |
</ul> | |
</header> | |
<nav > | |
<div class="tab selectedTab" id="position" ><span > </span><span >aboutMe</span><span > </span> | |
</div> | |
<div class="tab" id="friend" ><span > </span><span >friend</span><span > </span> | |
</div> | |
<div class="tab" id="theme" ><span > </span><span >lorem</span><span > </span> | |
</div> | |
<div class="tab" id="news" ><span > </span><span >repository</span><span > </span> | |
</div> | |
</nav> | |
<section id="my_position" class="eleDisplayShow" > | |
<ul > | |
<li > | |
<div class="myName" >blah blah !</div> | |
<div class="myDesc" >Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eaque recusandae hic obcaecati maxime officiis commodi! Cumque maiores maxime quam quidem deleniti, aspernatur iste, minima sit laboriosam laudantium saepe dignissimos provident.</div> | |
</li> | |
</ul> | |
</section> | |
<section id="my_friend"> </section> | |
<section id="my_theme" > </section> | |
<section id="my_news"> </section> | |
</div> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment