본문 바로가기

Javascript

Javascript & TypeScript Essential - 패스트캠퍼스 챌린지 8일차

#패스트캠퍼스_환급_챌린지 https://bit.ly/3FVdhDa #8일차

 

라우터? 화면 처리기 만들기

이전 시간에 간단하게 목록과 내용보는 화면을 구현했다.

그런데 목록에서 제목을 클릭하면 아래 내용(?)이 표시되었고, 계속 목록 제목을 클릭하면 클릭한 제목이 하단에 순차적으로 보여지고 있다.

이번시간에는 화면에 목록과 내용을 따로 표시하기로 하자.

먼저 내용  표시하는 부분이 DOM api가 아닌 지난 시간에 배운 HTML 문자열로 변경하는 작업 부터 해보자.

window.addEventListener('hashchange', function () {
  const id = location.hash.substr(1);

  const newsContent = getData(CONTENT_URL.replace('@id', id));
  //const title = document.createElement('h1');

  //title.innerHTML = `${ newsContent.title }`;

  //content.appendChild(title);
  container.innerHTML = `
    <h1>${ newsContent.title }</h1>
    <div>
      <a href="#">목록으로</a>
    </div>
  `;
});

내용에는 글 제목과 목록으로 이동할 수 있는 링크를 추가했다.

이제는 목록에서 제목을 클릭하면 내용(제목 + 목록으로 이동 링크)만 표시된다.

 

이번에는 내용에서 목록으로 이동 버튼을 클릭하면 목록이 표시될 수 있도록 목록을 처리하는 부분을 함수로 만들어 보자

먼저 기존 목록 프로그래밍을 배열에 문자열로 담아 마지막에 합쳐주는 방식으로 변경해보자.

// const ul = document.createElement('ul');
const newsList = [];
newsList.push('<ul>')
for (let i = 0; i < 10; i++) {
  //const div = document.createElement('div');

  newsList.push(`
    <li>
      <a href="#${ newsFeed[i].id }">
      ${ newsFeed[i].title } (${ newsFeed[i].comments_count })
      </a>
    </li>
  `);

  //ul.appendChild(div.firstElementChild);
}

//container.appendChild(ul);
//container.appendChild(content);
newsList.push('</ul>');
container.innerHTML = newsList.join('');

그리고 변경된 목록 처리 부분을 함수를 만들어 함수에서 구현하도록 해보자.

함수에서는 ajax로 뉴스목록을 가져오는 부분도 포함한다.

function newsFeed () {
  
  const newsFeed = getData(NEWS_URL);
  
  const newsList = [];
  newsList.push('<ul>');
  for (let i = 0; i < 10; i++) {
    newsList.push(`
      <li>
        <a href="#${ newsFeed[i].id }">
        ${ newsFeed[i].title } (${ newsFeed[i].comments_count })
        </a>
      </li>
    `);
  }
  newsList.push('</ul>');

  container.innerHTML = newsList.join('');
}

그리고 hashchange 이벤트 함수도 newsDetail이라는 함수로 정의해서 호출하는 것으로 변경한다.

function newsDetail () {
  const id = location.hash.substr(1);

  const newsContent = getData(CONTENT_URL.replace('@id', id));

  container.innerHTML = `
    <h1>${ newsContent.title }</h1>
    <div>
      <a href="#">목록으로</a>
    </div>
  `;

}

window.addEventListener('hashchange', newsDetail);

마지막으로 내용보기에서 목록으로 클릭시 목록이 표시될 수 있도록 router함수를 만들고 hashchange 이벤트를 연결하자.

router에서는 hash값을 가지고 목록(newsFeed)함수를 호출할 것인지 내용보기(newsDetail)함수를 호출한 것인지 판단하여 처리할 수 있도록 한다.

function router() {
  const routerPath  = location.hash;
  if (routerPath === '') {
    newsFeed();
  }
  else {
    newsDetail();
  }
}
window.addEventListener('hashchange', router);
router();	// 페이지 처음 접근 시 router함수를 통해 목록을 출력

이번시간까지 작성한 전체 소스이다.

const container = document.getElementById('root');
const ajax = new XMLHttpRequest();
const content = document.createElement('div');
const NEWS_URL ='https://api.hnpwa.com/v0/news/1.json';
const CONTENT_URL = 'https://api.hnpwa.com/v0/item/@id.json';

function getData (url) {
  ajax.open('GET', url, false);
  ajax.send();

  return JSON.parse(ajax.response);
}

function newsFeed () {
  
  const newsFeed = getData(NEWS_URL);
  
  const newsList = [];
  newsList.push('<ul>');
  for (let i = 0; i < 10; i++) {
    newsList.push(`
      <li>
        <a href="#${ newsFeed[i].id }">
        ${ newsFeed[i].title } (${ newsFeed[i].comments_count })
        </a>
      </li>
    `);
  }
  newsList.push('</ul>');

  container.innerHTML = newsList.join('');
}


function newsDetail () {
  const id = location.hash.substr(1);

  const newsContent = getData(CONTENT_URL.replace('@id', id));

  container.innerHTML = `
    <h1>${ newsContent.title }</h1>
    <div>
      <a href="#">목록으로</a>
    </div>
  `;

}

function router() {
  const routerPath  = location.hash;
  if (routerPath === '') {
    newsFeed();
  }
  else {
    newsDetail();
  }
}


window.addEventListener('hashchange', router);

router();

ch03_05.라우터?화면처리기만들기