1. JQuery
부분 로딩과 **SPA (Single Page Application)**는 웹 애플리케이션에서 성능 최적화와 사용자 경험 향상을 위한 중요한 개념입니다. 이 두 가지 개념을 자세히 설명해보겠습니다.
부분 로딩 (Partial Loading)
부분 로딩은 전체 페이지를 다시 로드하지 않고, 페이지의 일부분만을 동적으로 업데이트하거나 로드하는 기술입니다. 이는 웹 애플리케이션의 성능을 향상시키고 사용자 경험을 개선하기 위해 사용됩니다. 부분 로딩을 구현하는 일반적인 방법은 AJAX(Asynchronous JavaScript and XML), Fetch API, 또는 현대적인 프레임워크의 데이터 바인딩을 사용하는 것입니다.
주요 기술:
- AJAX (Asynchronous JavaScript and XML)
- 서버와 비동기적으로 통신하여 페이지를 새로고침하지 않고 데이터를 가져오거나 업데이트합니다.
- 예를 들어, 사용자가 버튼을 클릭할 때 서버에서 데이터를 가져와 페이지의 일부를 업데이트하는 데 사용됩니다.
javascript코드 복사
// AJAX 예제 (jQuery)
$.ajax({
url: '/data',
method: 'GET',
success: function(data) {
$('#content').html(data);
}
});
- Fetch API
- 현대적인 방법으로 AJAX 요청을 처리합니다.
fetch()
메소드를 사용하여 서버와 비동기적으로 데이터를 주고받을 수 있습니다.
javascript코드 복사
// Fetch API 예제
fetch('/data')
.then(response => response.text())
.then(data => {
document.getElementById('content').innerHTML = data;
});
- WebSocket
- 실시간 양방향 통신을 지원하여 서버와 클라이언트 간에 지속적으로 데이터를 주고받을 수 있습니다. 실시간 업데이트가 필요한 애플리케이션에서 유용합니다.
SPA (Single Page Application)
- *SPA (Single Page Application)**는 전체 페이지를 새로 로드하지 않고, 페이지의 콘텐츠를 동적으로 업데이트하는 웹 애플리케이션 아키텍처입니다. SPA는 사용자 경험을 매끄럽고 빠르게 만들어 주며, 페이지 전환 없이 동적인 콘텐츠 로딩을 지원합니다.
주요 특징:
- 동적 콘텐츠 로딩
- SPA는 페이지가 처음 로드될 때 필요한 모든 자바스크립트와 HTML 템플릿을 로드하고, 이후에는 클라이언트 측에서 동적으로 콘텐츠를 업데이트합니다.
- URL 변경은 클라이언트 측 라우터가 처리하며, 페이지 새로고침 없이도 다른 콘텐츠를 표시할 수 있습니다.
- 빠른 반응성
- 페이지 전환 시 전체 페이지를 새로 로드하지 않으므로, 사용자 인터페이스가 더욱 매끄럽고 빠르게 반응합니다.
- 서버와 비동기적으로 데이터를 주고받기 때문에 사용자 상호작용이 빠릅니다.
- 클라이언트 측 라우팅
- SPA는 클라이언트 측에서 라우팅을 처리하여 URL 경로에 따라 적절한 콘텐츠를 로드합니다. 이로 인해 URL 변경 시 서버와의 전체 페이지 로드 없이 콘텐츠를 업데이트할 수 있습니다.
- 클라이언트 측 라우팅 라이브러리 예: React Router, Vue Router
- 상태 관리
- SPA에서는 상태 관리가 중요하며, 클라이언트 측에서 애플리케이션의 상태를 유지하고 관리합니다.
- 상태 관리 라이브러리 예: Redux, MobX, Vuex
예시 프레임워크:
- React: 컴포넌트 기반으로 SPA를 구축할 수 있게 해주는 라이브러리입니다. React Router를 사용하여 클라이언트 측 라우팅을 지원합니다.
- Vue.js: Vue Router와 함께 사용하여 SPA를 구축할 수 있는 프레임워크입니다.
- Angular: 전체적인 SPA 프레임워크로, Angular Router와 함께 클라이언트 측 라우팅을 제공합니다.
2. JQuery 예시 코드
1. DOM 추가하기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.box {
border: 1px solid black;
padding: 10px;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head>
<body>
<h1>추가하기</h1>
<button onclick="addAppend()">append로 추가하기</button>
<button onclick="addPrepend()">prepend로 추가하기</button>
<button onclick="addBefore()">before로 추가하기</button>
<button onclick="addAfter()">after로 추가하기</button>
<div class="box" id="outerBox">
</div>
<script>
function render(id, text) {
return `<div class="box" id="${id}">${text}</div>
<div class="box" id="....">바보</div>
`;
}
function addAppend() {
let box = render("inner1", "내부박스1");
$("#outerBox").append(box);
}
function addPrepend() {
let box = render("inner2", "내부박스2");
$("#outerBox").prepend(box);
}
function addBefore() {
let box = render("outer1", "외부박스1");
$("#outerBox").before(box);
}
function addAfter() {
let box = render("outer2", "외부박스2");
$("#outerBox").after(box);
}
</script>
</body>
</html>
2. 반목문 리스트 만들고, 지우기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.box {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
border: 1px solid black;
padding: 10px;
}
.card {
border: 1px solid lightgray;
box-shadow: 0 4px 4px 0 grey;
padding: 10px;
margin: 5px;
border-radius: 5px;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head>
<body>
<h1>반복문으로 리스트 만들기</h1>
<button onclick="render()">render</button>
<div class="box" id="outerBox">
</div>
<script>
// 1. 그림그리기
function render() {
for (let i = 1; i < 5; i++) {
$("#outerBox").append(makeCard(i));
}
}
// 2. DOM 만들기
function makeCard(id) {
return `<div id="card-${id}" class="card">
<h3>제목${id} 입니다</h3>
<p>내용${id} 입니다</p>
<button onclick="del(${id})">삭제</button>
</div>`;
}
function del(id) {
$(`#card-${id}`).remove();
}
</script>
</body>
</html>
3. DOM 나타내기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.box {
border: 1px solid black;
padding: 10px;
}
</style>
</head>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<body>
<h1>숨기기</h1>
<button onclick="hideDisplay()">display로 숨기기</button>
<button onclick="hideVisible()">visible로 숨기기</button>
<div class="box">
<div class="box" id="innerBox1">
내부박스1
</div>
<div class="box" id="innerBox2">
내부박스2
</div>
</div>
<script>
function hideDisplay() {
$("#innerBox1").hide(); //display =none
}
function hideVisible() {
$("#innerBox1").remove(); // dom을 삭제합니다.
}
</script>
</body>
</html>
3. Ajax Fetch
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head>
<body>
<div id="root">
</div>
<script>
function makeDom() {
return `<div>그림</div>`;
}
//모든 그림이 그려야지 화면에 보임
async function download() { //비동기로 실행되어야 함 , fetch는
let response = await fetch("http://192.168.0.99:8080/test");
let data = await response.json();
$("#root").append(`<div>${data.body}</div>`);
}
$("#root").append(makeDom());
$("#root").append(makeDom());
download();
//callback
fetch("http://192.168.0.99:8080/test")
.then(res => res.json())
.then(res => { $("#root").append(`<div>${data.body}</div>`); })
$("#root").append(makeDom());
</script>
</body>
</html>
1. async function download()
async
키워드를 사용하면 해당 함수가 비동기 함수가 됩니다. 비동기 함수는 내부에서await
를 사용할 수 있으며, 함수가 실행될 때Promise
를 반환합니다.
2. let response = await fetch("http://192.168.0.99:8080/test");
fetch
함수는 주어진 URL(http://192.168.0.99:8080/test
)에 HTTP 요청을 보냅니다. 기본적으로 GET 요청을 보냅니다.
await
키워드는 이 비동기 요청이 완료될 때까지 코드를 기다리게 합니다.fetch
요청이 완료되면 응답 객체(response
)가 반환됩니다.
- 이 라인은 서버로부터 데이터를 요청하고 응답을 기다린 후, 그 응답을
response
변수에 저장하는 역할을 합니다.
3. let data = await response.json();
response.json()
은response
객체에서 JSON 데이터를 추출하는 메소드입니다. 이 메소드 또한 비동기이므로await
키워드를 사용해 데이터 추출이 완료될 때까지 기다립니다.
- 추출된 JSON 데이터는 자바스크립트 객체 형태로
data
변수에 저장됩니다.
4. $("#root").append(
<div>${data.body}</div>);
- 이 라인은 jQuery를 사용하여 DOM 조작을 합니다.
$("#root")
는id
가"root"
인 HTML 요소를 선택합니다.
append
메소드를 사용해 선택한 요소의 내부에 새로운 HTML 요소를 추가합니다.
${data.body}
는data
객체의body
속성 값을 HTML<div>
요소 안에 삽입합니다.
- 결과적으로 서버에서 받아온
data.body
값이id="root"
인 요소에 추가됩니다.
4-1. Ajax Fetch
<!DOCTYPE html>
<html lang="en">
<head>
<title>Blog</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
</head>
<body>
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="list.html">Metacoding</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#collapsibleNavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="collapsibleNavbar">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="save-form.html">글쓰기</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container p-5">
<div id="board-box"></div>
</div>
<footer class="bg-light p-5 text-center">
<h4>Created by Metacoding</h4>
<h5>☎ 010-2222-7777</h5>
<button class="btn btn-outline-primary">고객센터</button>
<button class="btn btn-outline-primary">오시는길</button>
</footer>
<script>
async function del(boardId) {
let response = await fetch("http://localhost:8080/board/" + boardId, {
method: "delete"
});
let data = await response.json();
console.log(data);
$(`#board-${boardId}`).remove();
}
async function getBoards() {
let response = await fetch("http://localhost:8080");
let data = await response.json();
//console.log(data);
let boardList = data.body;
for (board of boardList) {
let dom = makeBox(board);
$("#board-box").append(dom);
}
}
getBoards();
function makeBox(board) {
return `<div class="card mb-3" id="board-${board.id}">
<div class="card-body">
<div class="d-flex justify-content-between">
<div>
<h4 class="card-title mb-3">${board.title}</h4>
<span>${board.content}</span>
</div>
<button class="btn btn-outline-danger" onclick="del(${board.id})">삭제</button>
</div>
</div>
</div>`;
}
</script>
</body>
</html>
1. async function del(boardId)
async
키워드: 이 함수가 비동기적으로 실행된다는 것을 의미합니다. 비동기 함수는await
를 사용하여 비동기 작업을 동기처럼 처리할 수 있게 합니다.
boardId
: 함수가 호출될 때 넘겨받는 매개변수로, 삭제하려는 항목의 고유 ID를 나타냅니다.
2. let response = await fetch("http://localhost:8080/board/" + boardId, { method: "delete" });
fetch
함수: 주어진 URL에 HTTP 요청을 보냅니다. 이 URL은"http://localhost:8080/board/"
뒤에boardId
가 추가된 형태입니다. 이 URL은 백엔드 서버에서 특정boardId
를 가진 항목을 삭제하는 API 엔드포인트를 나타냅니다.
method: "delete"
: HTTP DELETE 메소드를 사용하여 요청을 보냅니다. 이 메소드는 주로 서버에서 자원을 삭제할 때 사용됩니다.
await
:fetch
요청이 완료될 때까지 코드의 실행을 중단하고, 응답이 오면 그 결과를response
변수에 저장합니다.
3. let data = await response.json();
response.json()
: 서버의 응답 데이터를 JSON 형식으로 파싱합니다. 이 작업도 비동기적으로 처리되므로,await
를 사용하여 JSON 파싱이 완료될 때까지 기다립니다.
data
변수: 파싱된 JSON 데이터를 자바스크립트 객체 형태로 저장합니다. 이 객체에는 서버에서 삭제 작업의 결과나 상태를 나타내는 정보가 들어 있을 수 있습니다.
4. console.log(data);
- 콘솔 출력: 서버에서 받은 응답 데이터를 콘솔에 출력합니다. 이 작업은 디버깅에 유용하며, 서버가 요청을 제대로 처리했는지 확인할 수 있습니다.
5. $(
#board-${boardId}).remove();
- jQuery 선택자:
id
속성이board-
와boardId
를 조합한 값(board-123
같은)을 가진 HTML 요소를 선택합니다.
remove
메소드: 선택된 요소를 DOM에서 제거합니다. 이 작업을 통해 삭제된 게시판 항목이 웹 페이지에서도 즉시 사라집니다.
4-2. 글쓰기(JSON)
<!DOCTYPE html>
<html lang="en">
<head>
<title>Blog</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
</head>
<body>
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="list.html">Metacoding</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#collapsibleNavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="collapsibleNavbar">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="save-form.html">글쓰기</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container p-5">
<!-- 요청을 하면 localhost:8080/board/save POST로 요청됨
title=사용자입력값&content=사용자값 -->
<div class="card">
<div class="card-header"><b>글쓰기 화면입니다</b></div>
<div class="card-body">
<form>
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter title" id="title">
</div>
<div class="mb-3">
<textarea class="form-control" rows="5" id="content"></textarea>
</div>
<button onclick="btnSave()" type="button" class="btn btn-primary form-control">글쓰기완료</button>
</form>
</div>
</div>
</div>
<footer class="bg-light p-5 text-center">
<h4>Created by Metacoding</h4>
<h5>☎ 010-2222-7777</h5>
<button class="btn btn-outline-primary">고객센터</button>
<button class="btn btn-outline-primary">오시는길</button>
</footer>
<script>
async function btnSave() {
// 1. dom에서 값 가져오기
let board = {
title: $("#title").val(),
content: $("#content").val()
};
// 2. json으로 변경하기
let reqBody = JSON.stringify(board);
// 3. fetch로 post 요청하기
let response = await fetch("http://localhost:8080/board", {
method: "post",
body: reqBody,
headers: {
'Content-Type': 'application/json; charset=utf-8',
}
});
let respBody = await response.json();
console.log("respBody", respBody);
// 4. 응답후 처리
location.href = "list.html";
}
</script>
</body>
</html>
코드설명
코드 설명
- DOM에서 값 가져오기:
- 사용자가 입력한 제목(
title
)과 내용(content
)을 jQuery를 이용해 DOM에서 가져옵니다.
javascript코드 복사
let board = {
title: $("#title").val(),
content: $("#content").val()
};
- JSON으로 변경하기:
- 가져온 데이터를 JSON 문자열로 변환합니다. 이때,
JSON.stringify()
를 사용해 JavaScript 객체를 JSON 문자열로 변환합니다.
javascript코드 복사
let reqBody = JSON.stringify(board);
- Fetch로 POST 요청하기:
fetch
API를 사용해 POST 요청을 보냅니다.- URL은
http://localhost:8080/board
이며, 요청 본문은reqBody
로 설정하고, 헤더에는Content-Type
을application/json
으로 설정해 JSON 데이터를 전송할 것을 명시합니다.
javascript코드 복사
let response = await fetch("http://localhost:8080/board", {
method: "post",
body: reqBody,
headers: {
'Content-Type': 'application/json; charset=utf-8',
}
});
- 응답 후 처리:
- 서버에서 받은 응답을 JSON으로 파싱하고, 콘솔에 출력합니다.
- 데이터 전송이 성공적으로 완료되면, 사용자를
list.html
페이지로 리다이렉트합니다.
javascript코드 복사
let respBody = await response.json();
console.log("respBody", respBody);
location.href = "list.html";
추가 설명
- await: 비동기 함수(
btnSave
) 내에서 사용되며,fetch
요청이 완료될 때까지 기다립니다. 요청이 완료된 후 다음 줄의 코드가 실행됩니다.
- Content-Type 헤더: 서버에 전송하는 데이터가 JSON 형식임을 알려줍니다.
- location.href: 요청이 성공적으로 완료되면 사용자를 목록 페이지(
list.html
)로 이동시킵니다.
주의사항
- 이 코드가 정상적으로 동작하려면 서버가
http://localhost:8080/board
경로에서 POST 요청을 받아 JSON 데이터를 처리할 수 있어야 합니다.
- 또한, 브라우저의 CORS(Cross-Origin Resource Sharing) 정책에 의해 다른 도메인에서 요청을 할 경우 문제가 발생할 수 있으므로, CORS 설정이 필요할 수 있습니다.
Share article