모던자바스크립트입문] 19장

19 API 활용

19.1 드래그 앤 드롭 API

19.1.1 드래그할 수 있게 만들기

드래그 앤 드롭을 사용하기 위해서는 HTML요소를 드래그할 수 있도록 해야합니다.
(HTML요소에 draggable속성을 지정합니다 : boolean)

<div draggable="true">드래그 할 수 있습니다.</div>

a[href]img[src]인 요소는 기본적으로 드래그할 수 있도록 만들어짐

19.1.2 드래그, 드롭 이벤트

이벤트 이름설명
drag드래그를 시작할 때 발생
dragstart드래그를 하는 동안 발생
dragend드래그가 끝났을 때 발생
dragenter마우스 포인터가 드롭 요소의 경계선 안쪽으로 들어갈 때 발생
dragover포인터가 경계선 안쪽에 있을 때 발생
dragleave바깥으로 나왔을 때 발생
drop요소에 드롭할 때 발생

drag와 dragover는 마우스가 움직이지 않더라도 주기적으로 발생함.

19.1.3 데이터 전달하기

각 이벤트는 dataTransfer 프로퍼티를 갖고있다.
이 객체로 드래그 타겟 요소가 드롭 타겟요소에 데이터를 전달할 수 있다.

DataTransfer 객체의 프로퍼티와 메서드

프로퍼티 이름/ 메서드 이름설명
typessetData 메서드로 설정한 데이터 타입 목록
files드래그한 파일 객체 목록
effectAllowed드래그 타겟 요소가 허용되는 작업의 유형
.(none, copy, copyLink, copyMove, link, linkMove, move, all, uninitialized )
dropEffect드롭 타겟 요소에 표시하는 효과(none, copy, move, link)
setData(format, data)타겟 요소의 데이터타입을 특정 데이터타입(format)으로 설정
getData(format)타겟 요소에서 데이터를 특정 타입(format)으로 가져온다 }
clearData(format)format타입으로 저장된 데이터 삭제. format지정하지 않을 경우 모든 데이터 삭제
setDragImage(element, x, y)드래그 이미지(드래그 중 표시되는 이미지) 설정. element는 img요소, x,y는 오프셋
addElement(element)타겟의 HTML요소(element)를 드롭타겟에 추가. 이 메서드를 호출하지 않아도 드롭하는 요소자체가 드래그 타겟의 HTML요소가 된다

드래그 타겟 -> 드롭타겟 데이터 전달 순서

  1. 드래그 타겟의 dragstart 이벤트 처리기에서 dataTransfer 프로퍼티의 setData메서드에 데이터 타입을 지정한 데이터를 추가
e.dataTransfer.setData('text/plain', value);
  1. 드롭 타겟 요소의 dragover 이벤트 처리기안에서 브라우저의 기본동작을 취소.
    드래그 타겟 요소가 드롭 타겟 요소 위에 올라가면 브라우저의 기본동작인 drop 이벤트가 취소되기때문
e.preventDefault();
  1. 드롭 타겟 요소의 drop 이벤트 처리기 안에서 dataTransfer 프로퍼티의 getData 메서드를 사용해 데이터를 지정한 데이터 타입으로 가져옴
var value = e.dataTransfer.getData('text/plain');

데이터는 데이터타입(format)별로 하나만 전달할 수 있다.
setData로 같은 데이터 타입의 데이터를 두번 설정시 이전에 설정한 데이터를 덮어쓴다

type값설명
text/plain일반 텍스트
text/htmlHTML 문자열
text/uri-listURL 문자열 목록

19.1.4 드래그 앤 드롭 예제

동작 : 색상설정 input 요소를 div에 드래그 앤 드롭하여 div요소의 색상 변경

drop이벤트 처리 시 preventDefault를 해야함
(링크나 파일이 드롭되면 브라우저가 그것을 표현하려하기 때문)

  • 드롭하는 영역을 사용자에게 알린다
    드롭 타겟 요소가 드롭하는 영역에 들어갔을 때 그곳이 드롭장소임을 알리면 사용자 편의성이 높아짐

예제

19.2 Blob

19.2.1 Blob

데이터 덩어리를 참조하는 용도로 사용된다
메모리상의 데이터(바이트 배열), 파일의 데이터 참조 가능

19.2.2 Blob 생성자

var blob = new Blob(source, { type : contentType });

Blob 생성자가 받는 인수
source : 버퍼배열
contentType : 생성하는 데이터 MIME 타입

source에 버퍼 여러개를 요소 지정 시 내부적으로 순차연결하여 Blob객체가 가리키는 하나의 버퍼가됨
(ArrayBuffer, TypedArray, DataView, Blob, String, 기타 모든 데이터 타입)
단, String은 UTF-8 바이너리로 변환됨.
그 외 모든 데이터 타입의 값은 toString 메서드로 문자열로 변환된 UTF-8바이너리로 변환됨.

프로퍼티 이름/메서드 이름설명
sizeBlob 객체가 참조하는 데이터의 크기(바이트 단위)
typeBlob 객체가 참조하는 데이터의 MIME 타입을 뜻하는 문자열
slice(start, end, contentType)버퍼의 start로부터 end까지의 복사본을 MIME타입이 contentType인 Blob객체로 반환

Blob객체_생성예

19.2.3 Blob 객체 가져오기

  1. Blob 생성자로 생성하는 방법
    Blob 생성자의 첫번째 인수로 ArrayBuffer나 형식화 배열등이 요소로 담긴 배열을 넘기면
    Blob 객체를 얻을 수 있음

  2. XMLHttpRequest로 웹 데이터를 HTTP 통신으로 가져오는 방법

function getBlob(url, callback) {
    var req = new XMLHttpRequest();
    req.onload = function() {
        callback(req.response);
    };
    req.open('GET', url);
    req.responseType = 'blob';
    req.send(null);
}
  1. postMessage로 다른 윈도우나 스레드에서 가져오는 방법

  2. 파일에서 가져오는 방법
    드래그 앤 드롭 API, 사용 시 파일을 읽어서 File객체로 가져올 수 있음
    File객체는 파일 이름, 수정일 등의 정보가 추가된 Blob객체

19.2.4 File 객체

Blob은 형식화 배열(TypedArray)처럼 메모리에 있는 데이터를 참조한다.
File은 로컬파일을 참조하는 Blob으로 File 객체를 사용하면 로컬파일을 읽거나 쓸 수 있다.

File객체는 Blob객체를 상속받은 객체이다.
Blob객체의 프로퍼티 외에도 추가로 읽기 전용 프로퍼티를 가지고있다.

프로퍼티설명
lastModifiedFile객체가 마지막으로 수정된 날짜(ms)
lastModifiedDataFile객체가 마지막으로 수정된 날짜(Date 객체)
nameFile 객체가 가리키는 파일의 이름
  • 로컬파일을 File 객체로 불러들이는 방법
  1. type='file' 속성을 지정한 input 요소로 불러오는 방법
    <input type='file'>
    input 요소로 선택한 파일의 File객체는 input 요소 객체의 files 프로퍼티에 저장된다.
    (files프로퍼티는 File객체의 배열)
    input 요소에 multiple 속성 지정 시 여러개의 파일을 선택하게 할 수 있다.

    <input type='file' multiple accept='image/*>
    accept 속성으로 선택할 수 있는 파일 유형을 MIME타입으로 설정할 수 있다.
    (image/*는 image/로 시작하는 모든 MIME타입을 의미함)

  2. 드래그 앤 드롭으로 불러들이기
    이벤트 객체의 dataTransfer 프로퍼티 안에 있는 files 프로퍼티에 저장된다.
    (files프로퍼티는 선택된 파일의 File 객체가 담긴 배열)

element.ondrop = function(e) {
    var files = e.dataTransfer.files;
}

19.2.5 FileReader

Blob 객체에는 데이터 내용을 읽는 메서드가 없다.
FileReader 객체 사용 시 Blob이 참조하는 데이터의 내용물(바이트배열 혹은 문자열)을 읽을 수 있다.

var reader = new FileReader();
메서드설명
readAsText(blob [, encoding])텍스트 형식으로 읽기
readAsArrayBuffer(blob)ArrayBuffer 형식으로 읽기
readAsDataURL(blob)data URL이 가리키는 데이터 읽기
readAsBinaryString(blob)이진 데이터 형식으로 읽기

데이터는 비동기로 읽어지며, load 이벤트 처리기 안에 콜백 작성
읽어들인 데이터는 FileReader객체의 result 프로퍼티에 저장됨

19.2.6 Blob URL

Blob은 Blob을 가리키는 URL을 가질 수 있다. 이것을 Blob URL이라고 한다.

// var blobURL = URL.createObjectURL(blob);

var a = new Uint8Array([1,2,3]);
var blob = new Blob([a], { type : 'application/octet-binary'});
var blobURL = URL.createObjectURL(blob);
console.log(blobURL); // blob:null/d92....

//revokeURL함수 사용 시 Blob URL을 메모리에서 해제할 수 있다
URL.revokeURL(blobURL);

예제;

  • Blob URL의 활용
    Blob URL은 일반적인 URL을 사용할 수 있는 곳이람녀 어디에서나 사용할 수 있다
  1. 이미지의 Blob URL을 img 요소의 src속성값으로 설정하면 그 데이터를 이미지로 표현할 수 있다.
var blobURL = URL.createObjectURL(blob);
var img = document.createElement('img');
img.src = blobURL;
  1. 이미지의 Blob URL을 img 요소 객체의 src 속성 값으로 설정하고 Canvas의 drawImage 메서드에 그 img 요소 객체를 넘기면 Canvas에 이미지를 그릴 수 있다.
var blobURL = URL.createObjectURL(blob);
var img = document.createElement('img');
img.onload = function() {
    ctx.drawImage(img, 0, 0);
    URL.revokeObjectURL(this.src);
};
img.src = blobURL;
  1. XMLHttpRequest가 읽어들일 URL로 설정 시 그 데이터를 텍스트로 읽을 수 있다
var blobURL = URL.createObjectURL(blob);
var req = new XMLHttpRequest();
req.onload = function() {
    callback(req.responseText);
}
req.open('GET', blobURL);
req.send(null);

19.2.7 그림판 프로그램에 기능 추가하기

  1. \<input type='file'>로 이미지 파일을 읽어들이기
  2. 드래그 앤 드롭으로 이미지 파일 읽어들이기
  3. 이미지 필터링 기능
  4. 이미지 저장 기능

19.3 Web Workers

특정 작업을 멀티스레드로 병렬처리 가능

19.3.1 Web Workers

클라이언트측 자바스크립트는 싱글스레드.
작업이 함수 단위로 실행되고 함수 하나를 실행하는 중에 다른함수 실행 불가

메인 스레드 : 클라이언트측 자바스크립트에서 정의한 스레드
워커 : Web Workers에서 병렬로 실행되는 스레드

워커와 메인스레드는 서로 다른 전역객체를 가지며, 상대방의 전역 객체를 참조할 수 없음
postMessage를 통한 통신만 가능

19.3.2 Web Worker 기본

  • Worker 객체 생성
var worker = new Worker('worker.js');
  • 워커에 메시지 보내기
// Window, Document객체를 제외한 모든 객체 가능
worker.postMessage('message');
  • 워커에서 메시지 받기
self.onmessage = function(e) {
    var message = e.data;
}
  • 워커 -> 메인스레드 메시지 보내기
self.postMessage('message');
  • 메인에서 워커의 메시지 받기
worker.onmessage = function(e) {
    var message = e.data;
}
  • 워커 스레드 강제종료

worker.terminate();

  • 스스로 종료

close();

  • 외부 스크립트 읽어들이기

importScripts를 사용해 워커안에 외부 스크립트파일을 읽어들일 수 있다.

importScripts('script.js')

19.3.3 워커로 할 수 있는 일

Blob 읽기, XMLHttpRequest와 같은 비동기 작업을 동기적으로 실행 가능
Web Workers 활용 시 동기적으로 실행하더라도 메인스레드에 정체가 발생하지 않음

  1. 워커에는 코어 자바스크립트의 모든 사양이 포함되어있다.
    워커의 전역객체는 self로 참조가능. self는 코어자바스크립트에 정의돈 모든 프로퍼티를 가지고 있고
    코어자바스크립트의 모든 기능 사용 가능.
    워커의 전역객체는 this로도 참조가능하나 window는 사용할 수 없음

  2. 클라이언트 측 자바스크립트 객체에 정의된 일부 프로퍼티 사용 가능

사용가능

  • setTimeout, setInterval, clearTimeout, clearInterval
  • Location 객체
  • Console 객체
  • addEventListener 메서드
  • XMLHttpRequest
  • 애플리케이션 캐시
  • 다른 Worker 객체의 생성

사용불가

  • DOM
  • Window 객체
  • Document 객체
  • parent 객체
  1. 일부 HTML 5 API 사용 가능
  • Blob
  • FileAPI(FileReader 등)
  • Indexed Database
  • Local Storage API
  • WebSockets
  1. 공유 워커 사용 가능
    여러 워커의 전역객체를 공유할 수 있는 워커. 공유워커는 SharedWorker 필요

좋은 웹페이지 즐겨찾기