[개발일기] 바닐라 JS 로 간단한 SPA 만들기 (class 활용)

Keunyeong Lee·2021년 12월 13일
0

[개발일기]

목록 보기
6/14
post-thumbnail
post-custom-banner

SPA 란?

: Single Page Application

여러개의 페이지를 한페이지만 로딩해서 구현하는 방식!
( 한번만 로딩되면 재로딩 되지 않고 여러 페이지와 컨텐츠를 이용할 수 있다. )

서버와의 통신을 할때에도 부분만을 변경한다. ajax통신 등을 활용하여 요청하고 데이터를 json 으로 받아와 페이지 전체가아닌 데이터가 필요한 부분만을 변경하고 사용한다.

SPA 장점!

페이지 로딩시간 단축.

필요한 정보만 ajax로 요청하여 받아볼 수 있기 때문에 로딩시에 많은 정보를 전부 받아올 필요가 없다.

더 쉽고 빠른 개발

여러가지 정보를 표시하기 위해 페이지를 여러개 만들 필요 없이 하나의 페이지에서 필요한 정보 혹은 필요한 환경을 만들기위해서 약간의 변화만 필요하기 때문에 개발도 빠르고 유지 관리도 간소화 된다.

오프라인 작업 능력

매번 페이지를 재로딩시키는 경우 오프라인 작업은 거의 불가능하다.

하지만 싱글 페이지의 경우 로컬 데이터를 효과적으로 캐시하여 사용자가 오프라인에서 작업할 수 있도록 한다.

인터넷 연결이 복원되면 오프라인 모드로 설정도니 모든 캐시 정보를 동기화 하여 사용할 수 있다.

향상된 사용자 경험

두 말 할 것 없이 매번 재로딩되는 MPA보다 빠르고 편하게 사용자는 사용할 수 있다.

모바일 어플리케이션 활용

SPA의 벡엔드 코드는 모바일 개발에도 편리하게 재사용이 가능하다.

SPA 단점

나쁜 SEO

높은 검색 순위를 달성하기 위해 적절하게 색인화 하는 작업이 어렵다.

보안문제

XSS(교차 사이트 스크립팅) 공격에 취약하다.

공격받을 경우 응용 프로그램에 다양한 악성 스크립트가 삽입되어 민감한 정보 누출이 일어날 수 있다.

방법

JS로 SPA를 만드는 여러가지 방법이 있지만 그 중 className을 활용하여 간단하게 만드는 방법으로 해보겠다!
( ajax통신등 데이터베이스와의 통신을 제외하고 html 로드와 동작 구현만을 다룬다.)

on : className 부여하기

function setMenu(_menu) {
  var filterButtons = document.querySelectorAll("nav li");
  filterButtons.forEach(function (filterButton) {
    filterButton.classList.remove("on"); // on 지우기
  });
  document.querySelector("nav li." + _menu).classList.add("on"); // on 넣기
  document.querySelector("main").className = _menu;
}

각 부분 요소 별로 페이지에 필요할때만 class 에 on 을 추가하여 display에 보이도록 한다. 보이지 않는 요소는 on 을 지워준다.

main 페이지 전체를 묶어서 관리하기

nav, footer를 제외하고 내부 컨텐츠 부분을 통째로 묶어서 각 메뉴별로 className 을 부여하고 해당메뉴를 선택했을 때 main contents 전체를 보여주도록 한다.

수정사항 표기

사진 아래 좋아요 표기를 하는 경우를 위한 준비.

사진을 로드할 때 사용되는 함수에 미리 이전에 띄워진 부분을 삭제하고 로드하도록 한다.

// 사진 띄우기 & 사진들 새로 보여주기 
function showPhotos () {

  // 현재 화면의 사진들 삭제
  // 수정 사항을 띄울 경우를 위해 삭제하고 로드하도록 한다.
  var existingNodes 
    = document.querySelectorAll("#gallery article:not(.hidden)");
  existingNodes.forEach(function (existingNode) {
    existingNode.remove();
  });

  // 갤러리 div 선택
  var gallery = document.querySelector("#gallery");

  photos.forEach(function (photo) {
    var photoNode = document.querySelector("article.hidden").cloneNode(true);
    photoNode.classList.remove("hidden");
    photoNode.querySelector(".author").innerHTML = photo.user_name;
    photoNode.querySelector(".desc").innerHTML = photo.description;
    photoNode.querySelector(".like").innerHTML = photo.likes;
    photoNode.querySelector(".like").addEventListener(
      "click", function () { toggleLike(photo.idx) }
    )
    photoNode.querySelector(".photo").style.backgroundImage 
      = "url('./img/photo/" + photo.file_name + "')";
    if (my_info.like.indexOf(photo.idx) > -1) {
      photoNode.querySelector(".like").classList.add("on");
    }
    gallery.append(photoNode);
  })
}

수정 사항이 있을 때면 함수를 통해 해당 요소를 지웠다가 다시 띄워준다.

리스트 전체를 다 지우고 다시 로드하는 방식으로 연산에 부담을 준다.

수정 부분만을 다시 로드하는 방식으로 작업해야 한다.

부분만을 수정하기 위한 함수를 따로 만들어 바꿔줄 수 있도록 한다.









#Ref)

https://dzone.com/articles/the-comparison-of-single-page-and-multi-page-appli

profile
🏃🏽 동적인 개발자
post-custom-banner

0개의 댓글