자기개발 챌린지(4주차_프로그래밍 첫걸음 시작하기:프로그래밍 기초)

EITA_0731·2022년 3월 8일
0
post-thumbnail

4주차 후기

4주차 강의는 Javascript 부분으로 웹사이트에서 동작에 따라 변화되는 내용을 만들어 보았다.

(1)실습 내용

  • 이번 Javascript부분은 별도 과제는 없이 같이 실습하면서 만들어나가는 과정으로 진행하였다.
  • header태그의 nav메뉴 선택시 화면 전환과 main태그 side-bar 보기옵션 클릭시 조건에 맞게 화면이 보여지는 기능을 만들면 된다.

(2)실습 결과물

1️⃣ header태그의 nav 메뉴 선택시 화면 전환

[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");
}

2️⃣ upload메뉴에서 input에 입력한 글자수 표기

[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";
}

3️⃣ 페이지 로드시 내정보 메뉴 셋팅

=> init함수에 showMyInfo함수 호출/body 태그에 속성 추가

4️⃣ 내정보 수정&확인&취소 버튼 기능 만들기

[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();
}

5️⃣ article 요소와 photo객체 보여주기

[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();
}

6️⃣ side-bar 정렬기능 넣기

[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) {
    	...
    }

4주차 수강 후기

기본 웹페이지에 생명을 불어 넣는다는 느낌이랄까. 버튼을 클릭 했을때 페이지가 보여지고 동작하는 것에 대한 재미가 느껴졌다. 처음 강의를 들을 때 객체나 배열의 자바스크립트 동작하는 게 아직은 버벅거리지만 두번째 혼자 하면서 함수 기능 및 동작을 제대로 이해할 수 있었다. 여러번 반복하다 보면 익숙해 질 것이라고 생각한다.

profile
기술 스택 : Javascript/Java/Spring Framework

0개의 댓글