개발자입니다
[비트캠프] 32일차(7주차2일) - jQuery(자바스크립트 라이브러리 만들기2, minify) 본문
[비트캠프] 32일차(7주차2일) - jQuery(자바스크립트 라이브러리 만들기2, minify)
끈기JK 2022. 12. 20. 15:43
메서드와 파라미터
그림 왼쪽 : hello() 함수 정의 = 연산자 정의
그림 오른쪽 : hello는 메서드(함수) = operator(연산자) 이다. ++a 에서 ++과 같이 작업수행 부분이다.
("홍길동")은 파라미터이다. ++a 에서 a와 같이 작업을 수행할 때 사용할 데이터이다.
++a에서 ++는 연산자(operator)이고 a는 피연산자(operand)이다.
메서드와 객체
-우측 상단 그림 : let obj = new Greeting("홍길동"); 하면 new로 ① 빈 객체 생성해서 Greeting() 에 주소 200 넘겨주고, 주소 200을 obj에 저장한다. ② object() 가 초기화, ③ Greeting() 이 초기화 시킨다.
new로 인스턴스를 생성하면 그 주소가 리턴된다.
-좌측 상단 그림 : this는 생성한 인스턴스의 주소를 가리킨다.
-좌측 하단 그림 : this는 생성한 인스턴스의 주소를 가리킨다.
-우측 하단 그림 : obj.hello("평어")는 이렇게 동작한다.
obj 는 메서드가 사용할 데이터이며 주데이터(피연산자)이다. obj 주소 200이 hello(변수 this)에 전달된다.
hello는 메서드(작업수행)이며 연산자이다.
("평어")는 메서드가 작업을 수행할 때 사용할 데이터이며 보조데이터(피연산자)이다.
함수를 정의한다 : 자신만의 연산자를 만든다.
jQuery 만들기 - 9. click()
.on('click', () => { 를 아래와 같이 바꾼다.
$("#btn1").click(() => {
// jQuery-09.js 추가
el.click = function (handler) {
for (let e of el) {
this.on('click', handler);
}
return this;
}
전체 코드
// jQuery-09.js
function jQuery(selector) {
let el = []; // 생성한 태그나 찾은 태그를 담는 배열
if (selector.startsWith("<")) {
el[0] = document.createElement(selector.substring(1, selector.length - 1));
} else {
let nodeList = document.querySelectorAll(selector);
for (let e of nodeList) {
el.push(e);
}
}
el.append = function (childBox) {
// 자식 태그를 복제해서 각 부모 태그에 붙인다.
for (let parent of el) {
// 자식들이 들어있는 상자에서 자식을 한 개씩 꺼내 복제하여 각 부모의 자식으로 붙인다.
for (let child of childBox) {
parent.appendChild(child.cloneNode(true));
}
}
// 자식 태그는 제거한다.
for (let child of childBox) {
if (child.parentElement != null || child.parentElement != undefined) {
child.parentElement.removeChild(child);
}
}
return el;
};
el.appendTo = function (parents) {
// 자식 태그를 복제해서 각 부모 태그에 붙인다.
for (let parent of parents) {
// 자식들이 들어있는 상자에서 자식을 한 개씩 꺼내 복제하여 각 부모의 자식으로 붙인다.
for (let child of el) {
parent.appendChild(child.cloneNode(true));
}
}
// 자식 태그는 제거한다.
for (let child of el) {
if (child.parentElement != null || child.parentElement != undefined) {
child.parentElement.removeChild(child);
}
}
return this;
};
el.html = function (content) {
for (let e of el) {
e.innerHTML = content;
}
return this;
};
el.on = function (eventName, listener) {
for (let e of el) {
e.addEventListener(eventName, listener);
}
return this;
};
el.click = function (handler) {
for (let e of el) {
this.on('click', handler);
}
return this;
}
return el;
}
var $ = jQuery;
jQuery 만들기 - 10. 리팩토링
html 수정 없이 jQuery 리팩토링 한다.
var tbody = $("tbody");
$("#btn1").click(() => {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var arr = JSON.parse(xhr.responseText);
for (var b of arr) {
$("<tr>")
.html("<td>" + b.no + "</td>" +
"<td>" + b.title + "</td>" +
"<td>" + b.writer + "</td>" +
"<td>" + b.viewCnt + "</td>")
.appendTo(tbody);
}
} else {
alert('데이터 요청 오류!');
}
}
};
xhr.open("GET", "http://localhost:3000/exam04-3", true);
xhr.send();
});
생성자를 정의한다. jQuery 함수 호출시마다 메서드 만들지 말고 생성자의 prototype에 공통 메서드 정의한다.
// jQuery-10.js
function jQuery(selector) {
return new ElementBox(selector);
}
function ElementBox(selector) {
this.el = []; // 생성한 태그나 찾은 태그를 담는 배열
if (selector.startsWith("<")) {
this.el[0] = document.createElement(selector.substring(1, selector.length - 1));
} else {
let nodeList = document.querySelectorAll(selector);
for (let e of nodeList) {
this.el.push(e);
}
}
}
ElementBox.prototype.append = function (childBox) {
for (let parent of this.el) {
for (let child of childBox.el) {
parent.appendChild(child.cloneNode(true));
}
}
for (let child of childBox) {
if (child.parentElement != null || child.parentElement != undefined) {
child.parentElement.removeChild(child);
}
}
return this;
};
ElementBox.prototype.appendTo = function (parentBox) {
for (let parentTag of parentBox.el) {
for (let child of this.el) {
parentTag.appendChild(child.cloneNode(true));
}
}
for (let child of this.el) {
if (child.parentElement != null || child.parentElement != undefined) {
child.parentElement.removeChild(child);
}
}
return this;
};
ElementBox.prototype.html = function (content) {
for (let e of this.el) {
e.innerHTML = content;
}
return this;
};
ElementBox.prototype.on = function (eventName, listener) {
for (let e of this.el) {
e.addEventListener(eventName, listener);
}
return this;
};
ElementBox.prototype.click = function (handler) {
return this.on('click', handler);
};
var $ = jQuery;
jQuery('#btn1') 하면 ElementBox의 인스턴스가 생성되고 변수 btn에 주소가 전달된다.
jQuery 만들기 - 11. ajax()
jQuery로 ajax 아래처럼 구현한다.
$("#btn1").click(() => {
$.ajax({
url: "http://localhost:3000/exam04-3",
method: "GET",
dataType: "json",
async: true,
success: (result) => {
for (var b of result) {
$("<tr>")
.html("<td>" + b.no + "</td>" +
"<td>" + b.title + "</td>" +
"<td>" + b.writer + "</td>" +
"<td>" + b.viewCnt + "</td>")
.appendTo(tbody);
}
},
error: () => {
alert('데이터 요청 오류!')
}
});
});
// jQuery-11.js 추가
jQuery.ajax = function (settings) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
let result;
if (settings.dataType == "json") {
// json string ---> javascript object (deserialize)
result = JSON.parse(xhr.responseText);
} else {
result = xhr.responseText;
}
settings.success(result);
} else {
settings.error();
}
}
};
xhr.open(settings.method, settings.url, settings.async);
xhr.send();
};
jQuery 만들기 - 12. ajax() 코드 정리
11. 에서 method, async 미지정시 default로 "GET", true 지정하도록 jQuery-12.js 수정한다.
$("#btn1").click(() => {
$.ajax({
url: "http://localhost:3000/exam04-3",
dataType: "json",
success: (result) => {
for (var b of result) {
$("<tr>")
.html("<td>" + b.no + "</td>" +
"<td>" + b.title + "</td>" +
"<td>" + b.writer + "</td>" +
"<td>" + b.viewCnt + "</td>")
.appendTo(tbody);
}
}
});
});
// jQuery-12.js 수정
jQuery.ajax = function (settings) {
if (settings.method == undefined) settings.method = "GET";
if (settings.async == undefined) settings.async = true;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
if (settings.success == undefined) {
return;
}
let result;
if (settings.dataType == "json") {
result = JSON.parse(xhr.responseText);
} else {
result = xhr.responseText;
}
settings.success(result);
} else {
if (settings.error == undefined) {
return;
}
settings.error();
}
}
};
xhr.open(settings.method, settings.url, settings.async);
xhr.send();
};
jQuery 만들기 - 13. get.JSON()
get 방식은 getJSON 함수를 통해 요청하도록 한다.
$("#btn1").click(() => {
$.getJSON("http://localhost:3000/exam04-3", (result) => {
for (var b of result) {
$("<tr>")
.html("<td>" + b.no + "</td>" +
"<td>" + b.title + "</td>" +
"<td>" + b.writer + "</td>" +
"<td>" + b.viewCnt + "</td>")
.appendTo(tbody);
}
});
});
// jQuery-13.js 추가
jQuery.getJSON = function (url, success) {
jQuery.ajax({
url: url,
dataType: "json",
success: success
})
};
jQuery 만들기 - 13. get.JSON() : forEach()로 배열 다루기
for를 forEach로 바꾼다.
$("#btn1").click(() => {
$.getJSON("http://localhost:3000/exam04-3", (result) => {
result.forEach((b) => {
$("<tr>")
.html("<td>" + b.no + "</td>" +
"<td>" + b.title + "</td>" +
"<td>" + b.writer + "</td>" +
"<td>" + b.viewCnt + "</td>")
.appendTo(tbody);
});
});
});
jQuery 만들기 - 14. val(), html()
이메일, 암호 전송하는 html이다.
.val() 에 인자 전달하지 않으면 getter로 동작하며, 인자 전달하면 setter로 동작한다.
<form id="login-form">
이메일: <input type="email" name="email" value="hong@gmail.com"><br>
암호: <input type="password" name="password"><br>
<button type="button" id="btn1">로그인</button>
<button type="button" id="btn2">취소</button>
</form>
<script>
$("#btn1").click(() => {
let email = $("#login-form > input[name='email']").val();
let password = $("#login-form > input[name='password']").val();
console.log(email, password);
});
$("#btn2").click(() => {
let email = $("#login-form > input[name='email']").val("");
let password = $("#login-form > input[name='password']").val("");
console.log(email, password);
});
jQuery 함수는 값을 꺼내는 함수(getter) 따로 넣는 함수(setter) 따로 있지 않다. 한 함수에서 값을 넣고 꺼내는 일을 한다.
파라미터 값이 있으면 값을 넣는 일을 하고, 파라미터 값이 없으면 꺼내는 일을 한다.
// jQuery-14.js
ElementBox.prototype.val = function (value) {
if (this.el.length == 0) {
return;
}
if (arguments.length > 0) {
// 값을 설정할 때는 모든 태그에 대해 수행한다.
for (let e of this.el) {
e.value = value;
}
return this;
} else {
// 값을 꺼낼 때는 맨 처음 태그 값만 꺼낸다.
return this.el[0].value;
}
};
jQuery 만들기 - 15. submit(), ajax() : POST 요청
button에 type 지정하지 않으면 기본 type은 submit이다. 취소 버튼 type은 reset으로 지정한다.
submit시 ajax() 실행되게 하며 인자로 객체에 url, method, dataType, data, success 담아 전달한다.
<form id="login-form">
이메일: <input type="email" name="email"><br>
암호: <input type="password" name="password"><br>
<button>로그인</button>
<button type="reset">취소</button>
</form>
<script>
var tbody = $("tbody");
$("#login-form").submit((e) => {
$.ajax({
url: "http://localhost:3000/login",
method: "POST",
dataType: "text",
data: {
email: $("#login-form > input[name='email']").val(),
password: $("#login-form > input[name='password']").val()
},
success: function () { }
})
// 따로 AJAX 요청을 할 것이기 때문에, 웹브라우저가 서버에 요청하는 것은 막는다.
e.preventDefault();
});
"POST" 방식일때 setRequestHeader 부분 추가하며, payload에 데이터 담아서 encodeURIComponent 사용해 전달한다.
// jQuery-15.js 수정
jQuery.ajax = function (settings) {
...
// 아래 부분 수정
if (settings.method == "POST") {
xhr.setRequestHeader(
"Content-Type",
"application/x-www-form-urlencoded");
let payload = "";
if (settings.data != undefined && settings.data != null) {
for (let key in settings.data) {
if (payload.length > 0) {
payload += "&";
}
payload += key + "=" + window.encodeURIComponent(settings.data[key]); // encodeURI 사용
}
}
xhr.send(payload);
} else {
xhr.send();
}
post 전달을 위해 서버쪽 작업을 한다.
// app.js 추가
app.post('/login', (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
res.set('Content-Type', 'text/plain;charset=UTF-8');
var payload = `이메일: ${req.body.email}\n`;
payload += `암호: ${req.body.password}\n`;
res.send(payload);
});
Payload에 데이터 나타난다.
jQuery 만들기 - 16. post()
$.ajax() 에서 $.post(요청주소, 데이터, 성공시 실행 함수) 로 바로 POST 요청한다.
$("#login-form").submit((e) => {
$.post("http://localhost:3000/login", {
email: $("#login-form > input[name='email']").val(),
password: $("#login-form > input[name='password']").val()
}, (result) => {
console.log(result);
});
e.preventDefault();
});
.post 메서드는 생성자 함수로 바로 등록한다.
// jQuery-16.js 추가
jQuery.post = function (url, data, success, dataType) {
jQuery.ajax({
url: url,
method: "POST",
dataType: dataType,
data: data,
success: success
});
};
jQuery 만들기 - 17. 자바스크립트 파일 압축
minifier 사용하여 공백, 엔터, 긴 변수명 줄여서 압축 시킨다.
// jQuery-16min.js
function jQuery(e){return new ElementBox(e)}function ElementBox(e){if(this.el=[],e.startsWith("<"))this.el[0]=document.createElement(e.substring(1,e.length-1));else{let t=document.querySelectorAll(e);for(let n of t)this.el.push(n)}}ElementBox.prototype.append=function(e){for(let t of this.el)for(let n of e.el)t.appendChild(n.cloneNode(!0));for(let o of e)(null!=o.parentElement||void 0!=o.parentElement)&&o.parentElement.removeChild(o);return this},ElementBox.prototype.appendTo=function(e){for(let t of e.el)for(let n of this.el)t.appendChild(n.cloneNode(!0));for(let o of this.el)(null!=o.parentElement||void 0!=o.parentElement)&&o.parentElement.removeChild(o);return this},ElementBox.prototype.html=function(e){if(0!=this.el.length){if(!(arguments.length>0))return this.el[0].innerHTML;for(let t of this.el)t.innerHTML=e;return this}},ElementBox.prototype.on=function(e,t){for(let n of this.el)n.addEventListener(e,t);return this},ElementBox.prototype.click=function(e){return this.on("click",e)},ElementBox.prototype.val=function(e){if(0!=this.el.length){if(!(arguments.length>0))return this.el[0].value;for(let t of this.el)t.value=e;return this}},ElementBox.prototype.submit=function(e){return this.on("submit",e)},jQuery.ajax=function(e){void 0==e.method&&(e.method="GET"),void 0==e.async&&(e.async=!0);var t=new XMLHttpRequest;if(t.onreadystatechange=()=>{if(4==t.readyState){if(200==t.status){if(void 0==e.success)return;let n;n="json"==e.dataType?JSON.parse(t.responseText):t.responseText,e.success(n)}else{if(void 0==e.error)return;e.error()}}},t.open(e.method,e.url,e.async),"POST"==e.method){t.setRequestHeader("Content-Type","application/x-www-form-urlencoded");let n="";if(void 0!=e.data&&null!=e.data)for(let o in e.data)n.length>0&&(n+="&"),n+=o+"="+window.encodeURIComponent(e.data[o]);t.send(n)}else t.send()},jQuery.getJSON=function(e,t){jQuery.ajax({url:e,dataType:"json",success:t})},jQuery.post=function(e,t,n,o){jQuery.ajax({url:e,method:"POST",dataType:o,data:t,success:n})};var $=jQuery;
'javascript minify' 검색해서 사용한다.
https://www.toptal.com/developers/javascript-minifier
jQuery 만들기 - 18. 오리지널 jQuery 사용하기
HTML에 다음 script 추가하면 jQuery 사용할 수 있다.
3.x.x 버전은 2.x.x 이하 버전에 있던 메서드나 변수 중 deprecated 되어 삭제된게 있을 수 있다.
실습하며 작성했던 html 코드에 오리지널 jQuery 소스 첨부해도 잘 돌아간다.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script>
"use strict"
var tbody = $("tbody");
$("#login-form").submit((e) => {
$.post("http://localhost:3000/login", {
email: $("#login-form > input[name='email']").val(),
password: $("#login-form > input[name='password']").val()
}, (result) => {
console.log(result);
});
e.preventDefault();
});
</script>
<table border="1">
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>조회수</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<button id="btn1">데이터 가져오기!</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script>
"use strict"
var tbody = $("tbody");
$("#btn1").click(() => {
$.getJSON("http://localhost:3000/exam04-3", (result) => {
result.forEach((b) => {
$("<tr>")
.html("<td>" + b.no + "</td>" +
"<td>" + b.title + "</td>" +
"<td>" + b.writer + "</td>" +
"<td>" + b.viewCnt + "</td>")
.appendTo(tbody);
});
});
});
</script>
UI control시
jQuery는 javascript가 주도하는 방식이다.
Bootstrap은 CSS가 주도하는 방식이다.
조언
*
과제
/
'네이버클라우드 AIaaS 개발자 양성과정 1기 > Javascript' 카테고리의 다른 글
[비트캠프] 34일차(7주차4일) - 해커톤: 공공데이터 이용 웹서비스 만들기 (0) | 2022.12.22 |
---|---|
[비트캠프] 33일차(7주차3일) - UI 다루기(Bootstrap vs jQuery) (0) | 2022.12.21 |
[비트캠프] 31일차(7주차1일) - jQuery(자바스크립트 라이브러리 만들기) (0) | 2022.12.19 |
[비트캠프] 30일차(6주차5일) - AJAX(제약, CORS, 프록시 기법, 동기/비동기 요청, 기상청 API 가져오기) (0) | 2022.12.16 |
[Javascript] getElement 메서드 비교 (0) | 2022.12.15 |