11. HTML5 API
1. 키워드
- Geolocation
- Drag and Drop
- Web Storage
- Application Cache
- Web Worker
- Server Sent Events
2. Geolocation
- Geolocation API는 사용자의 현재 위치 정보를 가져올 때 사용하는 자바스크립트 API이다.
- 사용자의 위도 및 경도에 관한 정보는 자바스크립트를 이용해 웹 서버로 전송된다.
- 이것을 이용하면 사용자의 위치를 지도에 표시하거나, 사용자 근처의 상점을 찾아주는 등의 위치기반 서비스를 할 수 있다.
- 하지만 이러한 정보는 사용자의 사생활을 침해할 가능성이 높으므로, 사용자의 동의 없이는 사용할 수 없도록 하고 있다.
Note
- 크롬 50.0 버전부터는 https와 같은 보안 프로토콜에서만 Geolocation API가 동작하도록 허용하고 있다.
1) getCurrentPosition()
메서드
getCurrentPosition()
메서드를 이용하면 사용자의 위치에 대한 위도와 경도값을 얻을 수 있다.- 이 메서드의 첫 번째 인수로는 가져온 사용자의 위치 정보를 출력하는 함수가 들어간다.
function findLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showYourLocation);
} else {
loc.innerHTML =
"이 문장은 사용자의 웹 브라우저가 Geolocation API를 지원하지 않을 때 나타납니다!";
}
}
- 이 메서드의 두 번째 인수로는 위치 정보에 관한 오류를 처리하는 함수가 들어간다.
function showErrorMsg(error) {
switch (error.code) {
case error.PERMISSION_DENIED:
loc.innerHTML =
"이 문장은 사용자가 Geolocation API의 사용 요청을 거부했을 때 나타납니다!";
break;
case error.POSITION_UNAVAILABLE:
loc.innerHTML =
"이 문장은 가져온 위치 정보를 사용할 수 없을 때 나타납니다!";
break;
case error.TIMEOUT:
loc.innerHTML =
"이 문장은 위치 정보를 가져오기 위한 요청이 허용 시간을 초과했을 때 나타납니다!";
break;
case error.UNKNOWN_ERROR:
loc.innerHTML = "이 문장은 알 수 없는 오류가 발생했을 때 나타납니다!";
break;
}
}
- 이처럼 가져온 사용자의 위치 정보를 구글 맵을 통해 표시할 수 있다.
function showYourLocation(position) {
var userLat = position.coords.latitude;
var userLng = position.coords.longitude;
var imgUrl =
"http://maps.googleapis.com/maps/api/staticmap?center=" +
userLat +
"," +
userLng +
"&zoom=15&size=500x400&sensor=false";
document.getElementById("mapLocation").innerHTML =
"<img src='" + imgUrl + "'>";
}
- 위의 예제처럼 단순한 이미지로 표시하는 것이 아닌 구글 맵 스크립트를 이용한 연동도 가능하다.
function showYourLocation(position) {
var userLat = position.coords.latitude;
var userLng = position.coords.longitude;
var userLocation = new google.maps.LatLng(userLat, userLng);
loc = document.getElementById("mapLocation");
loc.style.width = "500px";
loc.style.height = "400px";
var mapOptions = {
center: userLocation,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.SMALL,
},
};
var map = new google.maps.Map(loc, mapOptions);
var marker = new google.maps.Marker({
position: userLocation,
map: map,
title: "여기가 현재 위치입니다!",
});
}
2) Geolocation API 메서드
메서드 | 설명 |
---|---|
getCurrentPosition() |
사용자의 현재 위치를 가져옴. |
watchPosition() |
사용자의 현재 위치를 가져오고 나서, 사용자의 움직임에 따라 지속적으로 위치 정보를 갱신함. |
clearWatch() |
watchPosition() 메서드의 실행을 중지함. |
3) getCurrentPosition()
메서드의 반환값
속성 | 반환값 |
---|---|
coords.latitude |
소수로 표현된 위도 값 |
coords.longitude |
소수로 표현된 경도 값 |
coords.accuracy |
위도 값과 경도 값의 정확도 |
coords.altitude |
평균 해수면을 기준으로 하는 고도 값(해발) |
coords.altitudeAccuracy |
고도 값의 정확도 |
coords.heading |
북쪽을 기준으로 현재 진행 방향에 대한 시계방향으로의 각도 값(˚) |
coords.speed |
초당 이동한 미터 수를 나타내는 속도 값(초속) |
timestamp |
위치 정보를 가져온 시간을 나타냄. |
3. Drag and Drop
- 드래그 앤 드롭 API는 웹 페이지 내의 요소를 사용자가 자유롭게 드래그할 수 있도록 설정해준다.
- HTML5 이전에 이와 같은 기능을 구현하기 위해서는 엄청나게 많고 복잡한 스크립트를 작성해야 했다.
- 하지만 HTML5에서는 드래그 앤 드롭 기능이 표준 권고안에 포함되어 간단하게 사용할 수 있게 되었다.
- 현재 주요 웹 브라우저들은 모두 이 기능을 지원하며, 따라서 웹 페이지 내의 모든 요소는 드래그될 수 있다.
1) 드래그 앤 드롭 이벤트
- 마우스로 객체(Object)를 드래그해서 놓을 때까지 여러 단계의 이벤트가 순차적으로 발생하게 된다.
- 다음 표는 드래그 앤 드롭시 일어나는 이벤트를 순서대로 보여준다.
이벤트 | 설명 |
---|---|
dragstart |
사용자가 객체(Object)를 드래그하려고 시작할 때 발생함. |
dragenter |
마우스가 대상 객체의 위로 처음 진입할 때 발생함. |
dragover |
드래그하면서 마우스가 대상 객체의 위에 자리 잡고 있을 때 발생함. |
drag |
대상 객체를 드래그하면서 마우스를 움직일 때 발생함. |
drop |
드래그가 끝나서 드래그하던 객체를 놓는 장소에 위치한 객체에서 발생함. |
dragleave |
드래그가 끝나서 마우스가 대상 객체의 위에서 벗어날 때 발생함. |
dragend |
대상 객체를 드래그하다가 마우스 버튼을 놓는 순간 발생함. |
2) DataTransfer
객체
- 드래그 앤 드롭 이벤트를 위한 모든 이벤트 리스너 메서드(Event Listener Method)는
DataTransfer
객체를 반환합니다. - 이렇게 반환된
DataTransfer
객체는 드래그 앤 드롭 동작에 관한 정보를 가지고 있게 된다.
3) draggable
속성
- 웹 페이지 내의 모든 요소는
draggable
속성을 사용하여 드래그될 수 있는 객체(Draggable Object)로 변환될 수 있다.
4) ondragstart
속성
- 드래그될 수 있는 객체로 만든 후에는
ondragstart
속성을 통해DataTransfer
객체의setData()
메서드를 호출한다. setData()
메서드는 드래그되는 대상 객체의 데이터(Data)와 타입(Data Type)을 설정한다.
5) ondragover
속성
ondragover
속성은 드래그되는 대상 객체가 어느 요소 위에 놓일 수 있는지를 설정한다.- 기본적으로 HTML 요소는 다른 요소의 위에 위치할 수 없다.
- 따라서 다른 요소 위에 위치할 수 있도록 만들기 위해서는 놓일 장소에 있는 요소의 기본 동작을 막아야만 한다.
- 이 작업을
event.preventDefault()
메서드를 호출하는 것만으로 간단히 설정할 수 있다.
6) ondrop
속성
- 드래그하던 객체를 놓으면
drop
이벤트가 발생한다. ondrop
속성을 이용하여drop
이벤트에 대한 동작을 설정할 수 있다.
function dragEnter(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
4. Web Storage
- 웹 스토리지 API는 기존 쿠키(Cookie)의 문제점을 극복하기 위해 웹 브라우저가 직접 데이터를 저장할 수 있게 해준다.
- HTML5 이전에는 응용 프로그램이 데이터를 서버에게 요청할 때마다 매번 쿠키라는 곳에 그 정보를 저장한다.
- 하지만 웹 스토리지는 사용자 측에서 좀 더 많은 양의 정보를 안전하게 저장할 수 있도록 해준다.
- 웹 스토리지는 최소 5MB 이상의 많은 공간을 가지고 있으며, 이 정보는 절대 서버로 전송되지 않는다.
- 이러한 웹 스토리지는 오리진(Origin)마다 단 하나씩만 존재한다.
- 오리진이란 도메인(Domain)과 프로토콜(Protocol)의 한 쌍으로 이루어진 식별자이다.
- 따라서 하나의 오리진에 속하는 모든 웹 페이지는 같은 데이터를 저장하며 또한 같은 데이터에 접근할 수 있다.
1) 웹 스토리지 지원 여부 확인
- 웹 스토리지를 사용하기 전에, 우선 사용자의 웹 브라우저가 이를 지원하는지 안 하는지 확인해야 한다.
2) 웹 스토리지 객체
- 웹 스토리지 API는 사용자가 데이터를 저장할 수 있도록 두 가지 객체를 제공한다.
1] sessionStorage
객체: 하나의 세션(Session)만을 위한 데이터를 저장하는 객체
2] localStorage
객체: 보관 기한이 없는 데이터를 저장할 수 있는 객체
(1) sessionStorage
객체
sessionStorage
객체는 하나의 세션만을 위한 데이터를 저장한다.- 따라서 사용자가 브라우저 탭이나 창을 닫으면 이 객체에 저장된 데이터는 사라진다.
function clickCounter() {
if (typeof Storage !== "undefined") {
if (sessionStorage.clickcount) {
sessionStorage.clickcount = Number(sessionStorage.clickcount) + 1;
} else {
sessionStorage.clickcount = 1;
}
document.getElementById("counter").innerHTML =
"카운터의 현재 횟수는 " + sessionStorage.clickcount + "입니다!";
}
}
(2) localStorage
객체
localStorage
객체는 보관 기한이 없는 데이터를 저장한다.- 따라서 브라우저 탭이나 창이 닫히거나, 컴퓨터를 재부팅 해도 저장된 데이터는 없어지지 않는다.
function clickCounter() {
if (typeof Storage !== "undefined") {
if (localStorage.clickcount) {
localStorage.clickcount = Number(localStorage.clickcount) + 1;
} else {
localStorage.clickcount = 1;
}
document.getElementById("counter").innerHTML =
"카운터의 현재 횟수는 " + localStorage.clickcount + "입니다!";
}
}
5. Application Cache
- Application Cache API는 웹 응용 프로그램을 캐시(Cache)하여, 인터넷 접속 없이 사용자가 접근할 수 있게 해준다.
- 따라서 Application Cache를 사용하면 웹 응용 프로그램의 오프라인 버전을 쉽게 만들 수 있다.
- Application Cache를 사용해서 생기는 장점은 다음과 같다.
1] 오프라인 접속: 사용자가 웹 응용 프로그램을 오프라인(Off-line)으로도 사용할 수 있다.
2] 속도: 캐시된 자원은 빠르게 로드(Load)할 수 있다.
3] 서버의 부하 감소: 웹 브라우저는 서버의 자원에 변동이 있을 때만 자원을 갱신하면 된다.
1) Cache Mainfest 파일
- Application Cache를 사용하기 위해서는 먼저 Cache Mainfest 파일을 작성해야 한다.
- Cache Mainfest 파일은 웹 브라우저에 캐시해야 할 파일과 캐시하지 말아야 할 파일을 알려준다.
- 이러한 Cache Mainfest 파일은 다음과 같이 세 개의 세션(Session)으로 이루어진다.
1] CACHE MAINFEST
: 처음 다운로드한 이후에 계속 캐시할 파일들을 기록한다.
2] NETWORK
: 서버와의 접속이 필요한 파일들을 기록하며, 이 파일들은 절대로 캐시되지 않는다.
3] FALLBACK
: 파일에 접속할 수 없을 때에 대체할 파일들을 기록한다.
2) 캐시(Cache)의 갱신
- 웹 브라우저는 다음과 같은 경우가 발생하면 캐시의 정보를 갱신하게 된다.
1] 사용자가 웹 브라우저의 캐시를 강제로 지웠을 경우
2] Application Cache가 프로그램 때문에 갱신됐을 경우
3] Cache Mainfest 파일이 수정됐을 경우
CACHE MAINFEST
# 2016-03-22 v1.0.1
test.html
test.css
test.js
NETWORK:
test.jpg
FALLBACK:
/ offline.html
- 한 번 캐시되면 서버상의 파일을 수정해도, 웹 브라우저는 사용자 측에 캐시 되어 있는 버전의 파일만을 보여준다.
- 따라서 서버상의 파일을 수정한 후에는 반드시 웹 브라우저가 캐시를 갱신하도록 만들어야 한다.
- 이때 가장 많이 사용되는 방법이 Cache Mainfest 파일 내의 주석 부분을 수정하는 것이다.
- 일반적으로 갱신 날짜 및 버전 정보를 주석으로 표시하고, 이 부분을 수정하여 웹 브라우저가 캐시를 갱신하도록 유도한다.
6. Web Worker
- 웹 페이지에서 스크립트가 실행되면, 해당 웹 페이지는 실행 중인 스크립트가 종료될 때까지 응답 불가 상태가 된다.
- Web Worker는 스크립트가 웹 페이지의 성능에 영향을 미치지 않도록 백그라운드에서 동작하게 해주는 자바스크립트이다.
- 즉, Web Worker는 스크립트의 다중 스레드(Multi-thread)를 지원한다.
- 따라서 사용자가 웹 페이지를 이용하면서도, 동시에 시간이 오래 걸리는 자바스크립트 작업도 병행할 수 있도록 해준다.
1) Web Worker 지원 여부 확인
- Web Worker를 사용하기 전에, 우선 사용자의 웹 브라우저가 이를 지원하는지 안 하는지 확인해야 한다.
if (typeof(Worker) !== "undefined") {
// web worker를 위한 코드 부분 }
else {
// web worker를 지원하지 않는 브라우저를 위한 안내 부분
}
2) Web Worker 파일 생성
- Web Worker의 동작을 확인하기 위해 소수를 찾는 외부 자바스크립트 파일을 만든다.
var n = 1;
search: while (true) {
n += 1;
for (var i = 2; i <= Math.sqrt(n); i += 1) if (n % i == 0) continue search;
postMessage(n);
}
- 위의 예제에서
postMessage()
메서드는 HTML 문서에 결과를 전달하기 위해 사용한다.
3) Web Worker 객체 생성
- 위에서 만든 Web Worker 파일을 불러올 HTML 파일을 만든다.
- 위의 예제는 Web Worker 파일이 존재하지 않으면, 새로운 Web Worker 객체를 만들어 준다.
4) Worker
객체와의 연결
onmessage
이벤트 리스너(Event Listener)를 통해 Web Worker 파일과 메시지를 주고받을 수 있다.
webworker.onmessage = function (event) {
document.getElementById("result").innerHTML = event.data;
};
- 위의 예제에서 Web Worker 파일이 메시지를 보내면 해당 이벤트 리스너가 실행된다.
- 이 때 Web Worker 파일이 보낸 정보는
event.data
에 저장된다.
5) Web Worker 객체의 실행 종료
- Web Worker 객체는 생성되고 나서 종료될 때까지 계속해서 메시지를 받을 준비를 한다.
- 따라서 웹 브라우저나 컴퓨터의 자원을 돌려주기 위해서는
terminate()
메서드를 사용하여 Web Worker를 반드시 종료해줘야 한다.
6) Web Worker 객체의 재사용
- Web Worker 객체가 종료된 후에는 Web Worker의 값을
undefined
로 설정해야만 Web Worker 객체를 재사용할 수 있다.
7) Web Worker 예제
- 다음 예제는 앞에서 살펴본 Web Worker의 동작을 하나의 예제로 보여주는 예제이다.
var webworker;
function startWorker() {
if (typeof Worker !== "undefined") {
if (typeof webworker == "undefined") {
webworker = new Worker("/examples/web_worker.js");
}
webworker.onmessage = function (event) {
document.getElementById("result").innerHTML = event.data;
};
}
}
function stopWorker() {
webworker.terminate();
webworker = undefined;
}
7. Server Sent Events
- Server Sent Events API는 웹 페이지가 서버로부터 갱신된 정보를 자동으로 받을 수 있도록 설정한다.
1) Server Sent Events 지원 여부 확인
- Server Sent Events를 사용하기 전에, 우선 사용자의 웹 브라우저가 이를 지원하는지 안 하는지 확인해야 한다.
if (typeof EventSource !== "undefined") {
// server sent events를 위한 코드 부분
} else {
// server sent events를 지원하지 않는 브라우저를 위한 안내 부분
}
- 다음 예제는 Server Sent Events를 이용해
5
초마다 웹 페이지를 갱신하는 예제이다.
if (typeof EventSource !== "undefined") {
var source = new EventSource("/examples/media/sse.php");
source.onmessage = function (event) {
document.getElementById("result").innerHTML += event.data + "<br>";
};
}
- 위의 예제에서 사용한 서버 측 PHP 파일인
sse.php
파일은 다음과 같다.
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$time = date('r');
echo "data: The server time is: {$time}\n\n";
flush();
?>