학습목표
1. 함수 활용
양이 줄었는지 늘었는지
복잡도 증가했는지 줄었는지
2. 배열 CRUD
배열 내장함수(filter, join, push …)
3. DOM 구조 그리기(문자열을 이용한 HTML 다루기)
코드 양은 늘어나지만 직관적이라 유지보수 좋음
DOM API → 백틱(`) 기호로 변경(리팩토링)
4. 라우터 적용
5. 페이징 처리
6. TailWind CSS 적용
XMLHttpRequest
비동기통신객체
XHR 객체는 서버와 상호작용할 때 사용
XHR을 사용하면 페이지의 새로고침 없이도 URL에서 데이터를 가져올 수 있음
이를 활용하면 사용자의 작업을 방해하지 않고 페이지의 일부 업데이트 가능
// XMLHttpRequest는 내장객체가 아니다 → 인스턴스화를 해야 한다
const xhr = new XMLHttpRequest();
xhr.open(’GET|POST’, ‘url, false[비동기처리]|true[동기처리]); //상태값1
xhr.send(); // 상태값2
요청에대한 응답이 다운로드됨 //상태값3
다운로드가 완료 //상태값4
상태값 1~4에 따라 콜백함수 정의 → 시스템 호출 처리는 4번일 때 가능
<step 1>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>비동기 요청하기 - step1</title>
<script defer src="./app.js"></script>
</head>
<body>
<h2>비동기통신 객체로 요청보내고 응답 받기</h2>
<div id="title"></div>
</body>
</html>
const xhr = new XMLHttpRequest();
const NEWS = "https://api.hnpwa.com/v0/news/1.json";
xhr.open("GET", NEWS, false);
xhr.send();
const news = JSON.parse(xhr.responseText);
console.log(news);
// console.log(news[0].title);
// let element = document.createElement(tagName[, options]);
const ul = document.createElement("ul");
for (let i = 0; i < 10; i++) {
// 12번에서 생성한 ul태그 안에 li태그를 배열의 길이만큼 반복 생성
const li = document.createElement("li");
// 제목을 클릭하면 상세페이지 이동하기위한 링크 추가
const a = document.createElement("a");
a.href = "#";
a.innerHTML = `${news[i].title} (${news[i].comments_count})`;
// 위에서 만들어진 li태그를 ul태그에 하위태그로 붙임 -> appendChild
// var aChild = element.appendChild(aChild);
li.appendChild(a);
ul.appendChild(li);
} // end of for문
// console.log(xhr.responseText);
// console.log(ul);
document.querySelector("#title").appendChild(ul);
// document는 index.html 전체를 받는 객체이므로 js에서 사용불가
// document.write(xhr.responseText);
// div HTMLElement 받기
// const title = document.querySelector("#title");
// 요청으로 반환되는 타입은 이미 text, 즉 문자열이므로
// JSON.stringify는 사용할 필요가 없음
// 이미 문자열이니까 JSON.parse를 사용해서 구조를 분해하면 된다
// title.innerText = xhr.responseText;
// console.log(title);
<step 2>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>제목에대한 내용 확인페이지 - step2</title>
<script defer src="./app.js"></script>
</head>
<body>
<h2>제목에대한 내용 확인페이지</h2>
<div id="title"></div>
</body>
</html>
const xhr = new XMLHttpRequest();
const NEWS = "https://api.hnpwa.com/v0/news/1.json";
const CONTENT = "https://api.hnpwa.com/v0/item/@id.json";
const divContent = document.createElement("div"); // 제목에 대한 상세내용
xhr.open("GET", NEWS, false);
xhr.send();
const news = JSON.parse(xhr.responseText);
const ul = document.createElement("ul");
// 해시이벤트처리 추가
// 해시값이 변경되면 호출됨
window.addEventListener("hashchange", function () {
// console.log("해시가 변경됨");
// console.log(location.hash);
const id = this.location.hash.substring(1);
xhr.open("GET", CONTENT.replace("@id", id), false);
xhr.send();
console.log("before => ", CONTENT);
console.log("after => ", CONTENT.replace("@id", id));
const newsContent = JSON.parse(xhr.responseText);
const h1 = this.document.createElement("h1");
console.log(newsContent.title);
h1.innerHTML = newsContent.title;
divContent.appendChild(h1);
});
for (let i = 0; i < 10; i++) {
const li = document.createElement("li");
const a = document.createElement("a");
// a태그 안 href속성이 클릭을 감지할 수 있도록 해줌
a.href = `#${news[i].id}`;
a.innerHTML = `${news[i].title} (${news[i].comments_count})`;
li.appendChild(a);
ul.appendChild(li);
} // end of for문
document.querySelector("#title").appendChild(ul);
document.querySelector("#title").appendChild(divContent);
<step 3>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>반복코드 줄이기[선언적 함수 사용] - step3</title>
<script defer src="./app.js"></script>
</head>
<body>
<h2>반복코드 줄이기</h2>
<div id="title"></div>
</body>
</html>
const xhr = new XMLHttpRequest();
const NEWS = "https://api.hnpwa.com/v0/news/1.json";
const CONTENT = "https://api.hnpwa.com/v0/item/@id.json";
const divContent = document.createElement("div"); // 제목에 대한 상세내용
// 아래 함수의 사용처는 두 군데
// 요청 URL만 바뀜 나머지는 같음 -> 그래서 파라미터를 url로 줌
function getData(url) {
xhr.open("GET", url, false);
xhr.send();
return JSON.parse(xhr.responseText);
}
const news = getData(NEWS);
const ul = document.createElement("ul");
// 해시이벤트처리 추가
// 해시값이 변경되면 호출됨
window.addEventListener("hashchange", function () {
// console.log("해시가 변경됨");
// console.log(location.hash);
const id = this.location.hash.substring(1);
const newsContent = getData(CONTENT.replace("@id", id));
const h1 = this.document.createElement("h1");
console.log(newsContent.title);
h1.innerHTML = newsContent.title;
divContent.appendChild(h1);
});
for (let i = 0; i < 10; i++) {
const li = document.createElement("li");
const a = document.createElement("a");
// a태그 안 href속성이 클릭을 감지할 수 있도록 해줌
a.href = `#${news[i].id}`;
a.innerHTML = `${news[i].title} (${news[i].comments_count})`;
li.appendChild(a);
ul.appendChild(li);
} // end of for문
document.querySelector("#title").appendChild(ul);
document.querySelector("#title").appendChild(divContent);
<step 4>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>제목 클릭시 목록 없애기 - step4</title>
<script defer src="./app.js"></script>
</head>
<body>
<h2>제목 클릭시 목록 없애기</h2>
<div id="title"></div>
</body>
</html>
const xhr = new XMLHttpRequest();
const NEWS = "https://api.hnpwa.com/v0/news/1.json";
const CONTENT = "https://api.hnpwa.com/v0/item/@id.json";
const HOME = "http://127.0.0.1:5500/hackerNews/step6/index.html";
const container = document.querySelector("#title");
const divContent = document.createElement("div"); // 제목에 대한 상세내용
// 아래 함수의 사용처는 두 군데
// 요청 URL만 바뀜 나머지는 같음 -> 그래서 파라미터를 url로 줌
function getData(url) {
xhr.open("GET", url, false);
xhr.send();
return JSON.parse(xhr.responseText);
}
const news = getData(NEWS);
const ul = document.createElement("ul");
// 해시이벤트처리 추가
// 해시값이 변경되면 호출됨
window.addEventListener("hashchange", function () {
// console.log("해시가 변경됨");
// console.log(location.hash);
const id = this.location.hash.substring(1);
const newsContent = getData(CONTENT.replace("@id", id));
const h1 = this.document.createElement("h1");
container.innerHTML = `
<h1>${newsContent.title}</h1>
<div>
<a href = "${HOME}">목록으로</a>
</div>
`;
}); // end of hashchange
for (let i = 0; i < 10; i++) {
const div = document.createElement("div");
div.innerHTML = `
<li>
<a href = '#${news[i].id}'>
${news[i].title}(${news[i].comments_count})
</a>
</li>
`;
ul.appendChild(div.firstElementChild);
} // end of for문
container.appendChild(ul);
container.appendChild(divContent);
<step 4.5>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>라우터 적용 - step4.5</title>
<script defer src="./app.js"></script>
</head>
<body>
<h2>라우터 적용</h2>
<div id="title"></div>
</body>
</html>
const xhr = new XMLHttpRequest();
const NEWS = "https://api.hnpwa.com/v0/news/1.json";
const CONTENT = "https://api.hnpwa.com/v0/item/@id.json";
const container = document.querySelector("#title");
const divContent = document.createElement("div"); // 제목에 대한 상세내용
// 아래 함수의 사용처는 두 군데
// 요청 URL만 바뀜 나머지는 같음 -> 그래서 파라미터를 url로 줌
function getData(url) {
xhr.open("GET", url, false);
xhr.send();
return JSON.parse(xhr.responseText);
}
// 뉴스 목록 가져오기
function newsList() {
const news = getData(NEWS);
// li태그를 담을 배열 선언하기
const getList = [];
// li 태그를 담기 전에 ul태그 먼저 담기
getList.push("<ul>"); // push()는 배열의 끝에 요소를 추가하고 배열의 새로운 길이를 반환
for (let i = 0; i < 10; i++) {
const div = document.createElement("div");
getList.push(`
<li>
<a href = '#${news[i].id}'>${news[i].title}(${news[i].comments_count})</a>
</li>
`);
} // end of for
getList.push("</ul>");
// 빈문자열 주면 구분자 없는 하나의 합쳐진 HTML 문자열을 얻음
container.innerHTML = getList.join(""); // join()은 배열의 모든 요소를 연결해 하나의 문자열로 만듦
console.log(getList.join(""));
} // end of newsList
// 뉴스 상세 내용 보기
function newsDetail() {
const id = this.location.hash.substring(1);
const newsContent = getData(CONTENT.replace("@id", id));
const h1 = this.document.createElement("h1");
container.innerHTML = `
<h1>${newsContent.title}</h1>
<div>
<a href = '#'>목록으로</a>
</div>
`;
} // end of newDetail
// 라우터에서 화면 전환하기
function router() {
// 글 목록의 링크는 # -> location.href에 #에왔는데 왜 참인가?
// location.href에 #만 들어오면 빈값을 반환
// 그렇기에 이 코드가 작동하는 것
const routePath = location.hash;
console.log(routePath);
// 첫 진입일 때는 newsList를 호출한다
if (routePath === "") {
newsList();
} else {
newsDetail();
}
} // end of router
window.addEventListener("hashchange", router);
router();
'국비학원 > 수업기록' 카테고리의 다른 글
국비 지원 개발자 과정_Day50 (0) | 2023.02.08 |
---|---|
국비 지원 개발자 과정_Day49 (0) | 2023.02.07 |
국비 지원 개발자 과정_Day47 (1) | 2023.02.02 |
국비 지원 개발자 과정_Day46 (0) | 2023.02.01 |
국비 지원 개발자 과정_Day45 (0) | 2023.01.31 |
댓글