본 포스팅은 김정환님의 'jQuery 보다 먼저 알았으면 좋았을 것들' 포스팅을 보고 따라 정리해놓은 글입니다. 자세한 내용은 https://jeonghwan-kim.github.io/2018/01/25/before-jquery.html 링크를 참조해주세요!
<div id="app"></div>
$("#app")
=> JQuery를 활용한 돔 선택 (CSS 스타일의 선택자 사용)
document.getElementById("app")
document.querySelector("#app")
1) getElementById()
아이디로 돔을 찾는 DOM API
2) querySelector()
제이쿼리와 비슷하게 CSS 스타일의 선택자로 돔을 선택 가능
<div class="container"/></div>
$(".container")
=> JQuery
document.getElementsByClassName("container") document.querySelector(".container") document.querySelectorAll(".container")
1) getElementsByClassName()
: 클래스 명으로 돔을 찾는 API
(여러 개 돔을 유사 배열 형태로 반환!)
2) querySelector
/ querySelectorAll
: All이 붙으면 같은 클래스 애들 다 불러줌
<div data-product-id="G123">Guitar</div>
1) JQuery (data()
함수를 사용)
$("div").data("product-id")
2) Javascript
document.querySelector("div").dataset.productId
querySelector()
함수로 얻은 HTMLElement에는 dataset
이라는 객체가 있고,
이걸 통해서 data 속성 값에 접근할 수 있다. HTML 코드에서는 케밥 케이스로 표기하고 js 코드에서는 카멜 케이스라는 것이 다르다.
당연히 data 속성 값도 변경할 수 있다.
document.querySelector("div").dataset.productId = "G456"
하지만 dataset
은 IE 11 미만에서는 지원하지 않는다. 때문에 DATA 속성 값을 다루기 위해서는 일반 속성에 접근하기 위한 함수 getAttribute()
와 setAttribute()
함수를 사용해야 한다.
document.querySelector("div").getAttribute("data-product-id")
보통 jquery의 시작점은 ready()
함수로 설정한다.
$.ready(() -> {
// start...
})
document.addEventListener("DOMContentLoaded", () => {
// start...
})
HTML을 파싱한 뒤, DOM 객체를 생성이 완료되면 'DOMContentLoaded' 이벤트가 발생한다.
우리는 이 이벤트에 리스너를 추가하는 방식으로 똑같이 구현할 수 있다.
$("a").on("click", evt => {
// 이벤트 처리 ...
})
document.querySelector("a").addEventListener("click", evt => {
// 이벤트 처리 ...
})
$("a").click()
document.querySelector("a").click()
$("a").trigger("@click")
trigger()
함수를 이용하면 새로 정의한 '@click' 이벤트를 방출하게 된다.
const evt = new CustomEvent("@click", { detail : "some data" })
document.dispatchEvent(evt)
CustomEvent
생성시 두번째 인자로 detail
키를 갖는 객체만 넘겨주면 수신하는 측에서 이 값을 사용할 수 있다. 문자열 뿐만 아니라 객체도 가능하다.
document.querySelector("a").addEventListener("@click", evt => {
evt.detail // 'some data'
})
하지만, IE11 이하 버전에서는 CustomEvent
를 지원하지 않기 때문에 이벤트 생성하는 방법을 달리 해야한다.
const evt = document.createEvent("CustomEvent")
evt.initCustomEvent("@click", true, false, "some data")
document.dispatchEvent(evt)
document.createEvent()
함수로 생성한 이벤트 객체의 initCustomEvent()
함수로 이벤트 명과 전달할 데이터를 설정한다. 매개변수는 순서대로 이벤트명, 버블(bubble), 취송가능여부(cancelable), 전달할 데이터(detail)를 의미
돔 엘리먼트에 CSS 클래스를 추가하려면 어떻게 해야 할까
$("#foo").addClass("active")
addClass()
로 'active' 클래스를 추가했다.
document.querySelector("#foo").classList.add("active")
HTMLElement는 classList
라는 DOMTokenList를 반환한다.
이것은 클래스를 추가하는 add()
함수 뿐만 아니라, remove()
, toggle()
, contains()
같은 유용한 메소드를 제공한다.
하지만, 여전히 IE에서는 메소드 별로 지원 버전이 다르다.
때문에 폴리필을 추가하거나 다른 방법을 사용해야 한다.
document.querySelector("#foo").className += "active"
HTMLElement의 className
은 클래스 이름이 저장된 변수다. 이 문자열을 조작하면 클래스명을 추가/제거할 수 있다.
제이쿼리의 text()
함수로 제어하는 문자열은 HTMLElement의 innerHTML
로 가능하다.
$("#foo").text("hello sol")
document.querySelector("#foo").innerHTML = "hello sol"
제이쿼리의 ajax()
함수를 이용하면 서버 측에 비동기 요청을 보낼 수 있다.
$.ajax("/resource").then(success, fail)
const req = new XMLHttpRequest()
req.open("GET", "/resource", true)
req.onreadystatechange = () => {
if(req.readyState === 4) {
if(req.status === 200) success()
else faile()
}
}
req.send(null)
XMLHttpRequest
객체를 직접 사용하면 가능하다. GET, POST 뿐만 아니라 파일 업로드까지!
최근에 나온 fatch api를 사용해도 되지만 IE 브라우져 호환성이 필요하다면 라이브러리를 사용해야 한다.
제이쿼리의 ajax() 함수나 노드 진영에서 많이 사용하는 request 그리고 Vue.js에서 추천하는 axios 등이 대표적이다.
제이쿼리에서 여러 엘리먼트 배열을 순회할 때는 each()
함수를 사용
$("li").each(() => {
$(this) // li element
})
그럼 자바스크립트는?
Array.from(document.querySelectorAll("li")).foreach(li => {})
querySelectorAll()
함수는 유사배열을 반환한다.
Array의 프로토타입 함수를 사용하려면 Array.from()
함수를 이용해서 유사배열을 배열로 변환해야 한다.
이후에 Array.prototype.forEach()
함수를 이용해 li 엘리먼트를 순회할 수 있다.
Array.prototype
에는 map()
, reduce()
, every()
, some()
등 lodash같은 유틸리티 라이브러리에서 지원하는 컬렉션 함수가 있다.
객체 메소드도 살펴보자. 두 객체를 합칠 때(merge) 제이쿼리는 extend()
함수를 사용한다.
const obj3 = $.extend(obj1, obj2)
그럼 자바스크립트는?
const obj3 = Object.assign({}, obj1, obj2)
Object.assign()
함수를 이용해서 합친 새로운 객체를 만들어 낼 수 있다.