드래그 앤 드롭을 사용하기 위해서는 HTML요소를 드래그할 수 있도록 해야합니다.
(HTML요소에 draggable속성을 지정합니다 : boolean)
<div draggable="true">드래그 할 수 있습니다.</div>
a[href]
와 img[src]
인 요소는 기본적으로 드래그할 수 있도록 만들어짐
이벤트 이름 | 설명 |
---|---|
drag | 드래그를 시작할 때 발생 |
dragstart | 드래그를 하는 동안 발생 |
dragend | 드래그가 끝났을 때 발생 |
dragenter | 마우스 포인터가 드롭 요소의 경계선 안쪽으로 들어갈 때 발생 |
dragover | 포인터가 경계선 안쪽에 있을 때 발생 |
dragleave | 바깥으로 나왔을 때 발생 |
drop | 요소에 드롭할 때 발생 |
drag와 dragover는 마우스가 움직이지 않더라도 주기적으로 발생함.
각 이벤트는 dataTransfer 프로퍼티를 갖고있다.
이 객체로 드래그 타겟 요소가 드롭 타겟요소에 데이터를 전달할 수 있다.
DataTransfer 객체의 프로퍼티와 메서드
프로퍼티 이름/ 메서드 이름 | 설명 |
---|---|
types | setData 메서드로 설정한 데이터 타입 목록 |
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요소가 된다 |
드래그 타겟 -> 드롭타겟 데이터 전달 순서
e.dataTransfer.setData('text/plain', value);
e.preventDefault();
var value = e.dataTransfer.getData('text/plain');
데이터는 데이터타입(format)별로 하나만 전달할 수 있다.
setData로 같은 데이터 타입의 데이터를 두번 설정시 이전에 설정한 데이터를 덮어쓴다
type값 | 설명 |
---|---|
text/plain | 일반 텍스트 |
text/html | HTML 문자열 |
text/uri-list | URL 문자열 목록 |
동작 : 색상설정 input 요소를 div에 드래그 앤 드롭하여 div요소의 색상 변경
drop이벤트 처리 시 preventDefault를 해야함
(링크나 파일이 드롭되면 브라우저가 그것을 표현하려하기 때문)
데이터 덩어리를 참조하는 용도로 사용된다
메모리상의 데이터(바이트 배열), 파일의 데이터 참조 가능
var blob = new Blob(source, { type : contentType });
Blob 생성자가 받는 인수
source : 버퍼배열
contentType : 생성하는 데이터 MIME 타입
source에 버퍼 여러개를 요소 지정 시 내부적으로 순차연결하여 Blob객체가 가리키는 하나의 버퍼가됨
(ArrayBuffer, TypedArray, DataView, Blob, String, 기타 모든 데이터 타입)
단, String은 UTF-8 바이너리로 변환됨.
그 외 모든 데이터 타입의 값은 toString 메서드로 문자열로 변환된 UTF-8바이너리로 변환됨.
프로퍼티 이름/메서드 이름 | 설명 |
---|---|
size | Blob 객체가 참조하는 데이터의 크기(바이트 단위) |
type | Blob 객체가 참조하는 데이터의 MIME 타입을 뜻하는 문자열 |
slice(start, end, contentType) | 버퍼의 start로부터 end까지의 복사본을 MIME타입이 contentType인 Blob객체로 반환 |
Blob 생성자로 생성하는 방법
Blob 생성자의 첫번째 인수로 ArrayBuffer나 형식화 배열등이 요소로 담긴 배열을 넘기면
Blob 객체를 얻을 수 있음
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);
}
postMessage로 다른 윈도우나 스레드에서 가져오는 방법
파일에서 가져오는 방법
드래그 앤 드롭 API, 사용 시 파일을 읽어서 File객체로 가져올 수 있음
File객체는 파일 이름, 수정일 등의 정보가 추가된 Blob객체
Blob은 형식화 배열(TypedArray)처럼 메모리에 있는 데이터를 참조한다.
File은 로컬파일을 참조하는 Blob으로 File 객체를 사용하면 로컬파일을 읽거나 쓸 수 있다.
File객체는 Blob객체를 상속받은 객체이다.
Blob객체의 프로퍼티 외에도 추가로 읽기 전용 프로퍼티를 가지고있다.
프로퍼티 | 설명 |
---|---|
lastModified | File객체가 마지막으로 수정된 날짜(ms) |
lastModifiedData | File객체가 마지막으로 수정된 날짜(Date 객체) |
name | File 객체가 가리키는 파일의 이름 |
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타입을 의미함)
드래그 앤 드롭으로 불러들이기
이벤트 객체의 dataTransfer 프로퍼티 안에 있는 files 프로퍼티에 저장된다.
(files프로퍼티는 선택된 파일의 File 객체가 담긴 배열)
element.ondrop = function(e) {
var files = e.dataTransfer.files;
}
Blob 객체에는 데이터 내용을 읽는 메서드가 없다.
FileReader 객체 사용 시 Blob이 참조하는 데이터의 내용물(바이트배열 혹은 문자열)을 읽을 수 있다.
var reader = new FileReader();
메서드 | 설명 |
---|---|
readAsText(blob [, encoding]) | 텍스트 형식으로 읽기 |
readAsArrayBuffer(blob) | ArrayBuffer 형식으로 읽기 |
readAsDataURL(blob) | data URL이 가리키는 데이터 읽기 |
readAsBinaryString(blob) | 이진 데이터 형식으로 읽기 |
데이터는 비동기로 읽어지며, load 이벤트 처리기 안에 콜백 작성
읽어들인 데이터는 FileReader객체의 result 프로퍼티에 저장됨
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);
예제;
var blobURL = URL.createObjectURL(blob);
var img = document.createElement('img');
img.src = blobURL;
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;
var blobURL = URL.createObjectURL(blob);
var req = new XMLHttpRequest();
req.onload = function() {
callback(req.responseText);
}
req.open('GET', blobURL);
req.send(null);
특정 작업을 멀티스레드로 병렬처리 가능
클라이언트측 자바스크립트는 싱글스레드.
작업이 함수 단위로 실행되고 함수 하나를 실행하는 중에 다른함수 실행 불가
메인 스레드 : 클라이언트측 자바스크립트에서 정의한 스레드
워커 : Web Workers에서 병렬로 실행되는 스레드
워커와 메인스레드는 서로 다른 전역객체를 가지며, 상대방의 전역 객체를 참조할 수 없음
postMessage를 통한 통신만 가능
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')
Blob 읽기, XMLHttpRequest와 같은 비동기 작업을 동기적으로 실행 가능
Web Workers 활용 시 동기적으로 실행하더라도 메인스레드에 정체가 발생하지 않음
워커에는 코어 자바스크립트의 모든 사양이 포함되어있다.
워커의 전역객체는 self로 참조가능. self는 코어자바스크립트에 정의돈 모든 프로퍼티를 가지고 있고
코어자바스크립트의 모든 기능 사용 가능.
워커의 전역객체는 this로도 참조가능하나 window는 사용할 수 없음
클라이언트 측 자바스크립트 객체에 정의된 일부 프로퍼티 사용 가능
사용가능
- setTimeout, setInterval, clearTimeout, clearInterval
- Location 객체
- Console 객체
- addEventListener 메서드
- XMLHttpRequest
- 애플리케이션 캐시
- 다른 Worker 객체의 생성
사용불가
- DOM
- Window 객체
- Document 객체
- parent 객체