4주차 강의는 Javascript 부분으로 웹사이트에서 동작에 따라 변화되는 내용을 만들어 보았다.
[html]
<nav class="nav">
<ul>
<li class="gallery on" onclick="setMenu('gallery')">사진들 보기</li>
<li class="upload" onclick="setMenu('upload')">사진 올리기</li>
<li class="myinfo" onclick="setMenu('myinfo')">내 정보</li>
</ul>
</nav>
[Javascript]
function setMenu(_menu) {
//main 요소 클래스 설정
document.querySelector("main").className = _menu;
//모든 메뉴 버튼의 on 해제하기
let filterButtons = document.querySelectorAll("nav li");
filterButtons.forEach(function(filterButton) {
filterButton.classList.remove("on");
});
//선택한 메뉴 버튼 on으로 설정하기
document.querySelector("nav li."+_menu).classList.add("on");
}
[html]
<div class="instruction">나만의 특별한 사진을 업로드합니다.</div>
<input class="description" type="text" maxlength="20" placeholder="사진 설명을 20자 이내로 적어주세요." onkeyup="setDescLength()"/>
<span class="descLength">0/20</span>
[Javascript]
//글자수 입력 표기 함수
function setDescLength() {
let descLength = document.querySelector(".descLength");
let description = document.querySelector(".description");
descLength.innerHTML = description.value.length + "/20";
}
=> init함수에 showMyInfo함수 호출/body 태그에 속성 추가
[html]
<div class="mi-dep non-edit button" onclick="setEditMyInfo(true)">수정</div>
<div class="mi-dep edit button" onclick="updateMyInfo()">확인</div>
<div class="mi-dep edit button cancel" onclick="setEditMyInfo(false)">취소</div>
[javascript]
//내정보 보여주기
function showMyInfo() {
//my_info 항목 내용 채우기
document.querySelector("#myInfoId").innerHTML = my_info.id;
document.querySelector("#myInfoUserName").innerHTML = my_info.user_name;
document.querySelector("#sp-intro").innerHTML = my_info.introduction;
document.querySelector("#ip-intro").value = my_info.introduction;
//radio타입 input 체크 설정
document.querySelector("#myinfo input[type=radio][value="+my_info.as+"]").checked = true;
//checkbox타입 input 체크 설정
//interest항목 전체 check해제 하기
document.querySelectorAll("#myinfo input[type=checkbox]")
.forEach(function(checkbox) {
checkbox.checked = false;
});
//myinfo interest항목 check설정 하기
my_info.interest.forEach(function(interest) {
document.querySelector("#myinfo input[type=checkbox][value="+interest+"]").checked = true;
});
}
//myinfo 수정 모드 켜고 끄기
function setEditMyInfo (on) {
//"edit","non-edit"요소 클래스 선택
document.querySelector("#myinfo > div").className = on ? "edit" : "non-edit";
//input항목 입력 활성화
document.querySelectorAll("#myinfo input").forEach(function(input) {
input.disabled = !on;
});
//수정하다 취소시 입력창 원상복구
showMyInfo();
}
function updateMyInfo() {
//소개input 수정한 값 저장
my_info.introduction = document.querySelector("#ip-intro").value;
//취미input 수정한 값 저장
my_info.as = document.querySelector("#myinfo input[type=radio]:checked").value;
//흥미input 배열로 수정한 값 저장
let interests = [];
document.querySelectorAll("#myinfo input[type=checkbox]:checked")
.forEach(function(checked) {
interests.push(checked.value);
});
my_info.interest = interests;
//취소버튼 선택시 원래값 그대로 저장
setEditMyInfo(false);
//확인버튼 선택시 수정 저장된 값 반영하여 저장
showMyInfo();
}
[html]
<section id="gallery" class="dep _gallery ">
<article class="hidden">
<div class="photo"></div>
<div class="info">
<div class="like"></div>
<div class="author"></div>
<div class="desc"></div>
</div>
</article>
</section>
[Javascript]
//photos 객체 보여주기
function showPhotos() {
//현존하는 썸네일 삭제
let existingNodes = document.querySelectorAll("#gallery article:not(.hidden)");
existingNodes.forEach(function(existingNode) {
existingNode.remove();
});
//gallery클래스 선택
let gallery = document.querySelector("#gallery");
photos.forEach(function(photo) {
//photos객체 보여주기 위한 클론노드 만들고 숨김 풀기
let photoNode = document.querySelector("article.hidden").cloneNode(true);
photoNode.classList.remove("hidden");
//photos 객체 저장
photoNode.querySelector(".author").innerHTML = photo.user_name;
photoNode.querySelector(".desc").innerHTML = photo.description;
photoNode.querySelector(".like").innerHTML = photo.likes;
photoNode.querySelector(".photo").style.backgroundImage
= "url('./img/photo/"+photo.file_name+"')";
// my_info like 선택 시 heart on 표시
if (my_info.like.indexOf(photo.idx) > -1) {
photoNode.querySelector(".like").classList.add("on");
}
// toggle버튼 리스너
photoNode.querySelector(".like").addEventListener(
"click", function () { toggleLike(photo.idx) }
);
//photoNode에 저장한 객체 gallery에 보내기
gallery.append(photoNode);
});
}
function toggleLike(idx) {
if(my_info.like.indexOf(idx) === -1) {
//my_info가 좋아요하지 않은 사진일 때 -> 좋아요로 바꿈
my_info.like.push(idx);
for(let i=0 ; i<photos.length ; i++) {
if(photos[i].idx === idx) {
photos[i].likes++;
break;
}
}
} else {
//my_info가 좋아요한 사진일 때 -> 좋아요 해제
my_info.like = my_info.like.filter(function (it) {
return it !== idx;
});
for (var i = 0; i < photos.length; i++) {
if (photos[i].idx === idx) {
photos[i].likes--;
break;
}
}
}
showPhotos();
}
[html]
<ul id="sorts" class="dep _gallery">
<li class="recent on" onclick="setSort('recent')">최신순 보기</li>
<li class="like" onclick="setSort('like')">좋아요 순 보기</li>
</ul>
<ul id="filters" class="dep _gallery">
<li class="all on" onclick="setFilter('all')">전체 사진</li>
<li class="mine" onclick="setFilter('mine')">내 사진 사진</li>
<li class="like" onclick="setFilter('like')">좋아요 한 사진</li>
<li class="follow" onclick="setFilter('follow')">팔로우 회원 사진</li>
</ul>
[Javascript]
//정렬방식(최신순,좋아요순)
let sorts = {
recent: function (a, b) { return (a.idx > b.idx) ? -1 : 1 },
like: function (a, b) { return (a.likes > b.likes) ? -1 : 1 }
};
//현재 정렬방식(최신순)
let sort = sorts.recent;
//side-bar 메뉴 선택시 정렬 및 on 표시
function setSort(_sort) {
//모든 메뉴 on 제거
let sortButtons = document.querySelectorAll("#sorts li");
sortButtons.forEach(function(sortButton) {
sortButton.classList.remove('on');
});
//선택한 메뉴에 on 표시
document.querySelector("#sorts ."+_sort).classList.add("on");
sort = sorts[_sort];
showPhotos();
}
//필터방식(전체,내사진,좋아요한 사진,팔로우한 사진)
let filters = {
all: function (it) { return true; },
mine: function (it) { return it.user_id === my_info.id; },
like: function (it) { return my_info.like.indexOf(it.idx) > -1; },
follow: function (it) { return my_info.follow.indexOf(it.user_id) > -1; }
}
//현재 필터방식(전체)
let filter = filters.all;
//side-bar 메뉴 선택시 필터 및 on 표시
function setFilter(_filter) {
//모든 메뉴 on 제거
let filterButtons = document.querySelectorAll("#filters li");
filterButtons.forEach(function(filterButton) {
filterButton.classList.remove('on');
});
//선택한 메뉴에 on 표시
document.querySelector("#filters ."+_filter).classList.add("on");
filter = filters[_filter];
showPhotos();
}
⏹showphotos() 함수에 필터&정렬 적용하기
var filtered = photos.filter(filter);
filtered.sort(sort);
filtered.forEach(function(photo) {
...
}
기본 웹페이지에 생명을 불어 넣는다는 느낌이랄까. 버튼을 클릭 했을때 페이지가 보여지고 동작하는 것에 대한 재미가 느껴졌다. 처음 강의를 들을 때 객체나 배열의 자바스크립트 동작하는 게 아직은 버벅거리지만 두번째 혼자 하면서 함수 기능 및 동작을 제대로 이해할 수 있었다. 여러번 반복하다 보면 익숙해 질 것이라고 생각한다.