- 2010-01-12
- HTML5
take©です。
まずはこれをみていただきたい。
Amazing! ブラウザにドロップした画像ファイルの内容が表示されているではないですか。 さらには、テキストファイル、動画ファイル、Webページのサムネイルまでドラッグ&ドロップで表示できています。 ついにここまで来たんですね。
元ネタはこれ。
モジラのHacks Blogで公開されたDrag and Drop APIとFile APIを使ったデモです。
http://hacks.mozilla.org/2009/12/file-drag-and-drop-in-firefox-3-6/ (元記事)
http://demos.hacks.mozilla.org/openweb/DnD/ (デモ)
このデモはFirefox 3.6 betaが実装したHTML5の新しい規格、Drag and Drop APIとFile APIで実現されています。 そのため、デモはFirefox 3.6 beta以上でなければ動きません。
どうやってドロップイベントを取得しているのか?
ソースファイルをチラ見するとこんなことをやっていました。
function init() { window.addEventListener("dragenter", dragenter, true); dropbox = document.getElementById("dropbox"); window.addEventListener("dragleave", dragleave, true); dropbox.addEventListener("dragover", dragover, true); dropbox.addEventListener("drop", drop, true); }
dragenter、dragleave、dragover、dropなど様々なイベントがハンドリングできるんですね。 これがDrag and Drop API。
どうやってドロップされたファイルの中身をHTMLに表示させているのか?
Firebugでドロップした画像のimgタグを覗いてみたらこんなことになってました。
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEA...(略)"/>
今まではimgタグのsrc属性にはファイルのパスを指定していましたよね?
でもこれはなにやらmimeタイプとエンコード方式、エンコードされた画像のバイナリデータが指定してあるようです。
これまた、驚きですね。
そう、つまりJavascriptでドラッグされたファイルの中身が取得できるのです。
ソースを見れば、ドロップイベントのインターフェイス "dataTransfer" を使ってファイルハンドラを取得しているのがわかります。 IF文はドラッグされたものが、ファイルなのか、データそのもの(文字を反転してドラッグした場合など)なのかを判定していますね。
function drop(e) { var dt = e.dataTransfer; var files = dt.files; e.preventDefault(); if (files.length == 0) { handleData(dt); return; } for (var i = 0; i < files.length; i++) { var file = files[i]; handleFile(file); } }
そしてここからがFile APIの登場。 Fileインターフェイスでファイルの種別を、File Readerインターフェイスでファイルの読み込みを行い、imgタグのsrcに突っ込んでます。
function handleFile(file) { var imageType = /image.*/; var videoType = /video.*/; var audioType = /audio/; var textType = /text.*/; var bag = document.getElementById("bag"); if (!file.type.match(imageType) && !file.type.match(videoType) && !file.type.match(audioType) && !file.type.match(textType)) { return false; } if(file.type.match(imageType)) { var img = document.createElement("img"); var reader = new FileReader(); reader.onloadend = function() { img.src = reader.result; } reader.readAsDataURL(file); img.classList.add("obj"); bag.insertBefore(img, bag.firstChild); }
どうやってWebページのサムネイルを表示しているのか?
デモでWebページのサムネイルが表示されているものかなり衝撃的です。 画像やテキストはバイナリを取得しているとして、Webページはいったいどうやって?
ポイントは2つ。
1つ目はdataTransferで取得できるデータタイプの判定。
2つ目はiframeとCSS。
// browser tab var type0 = "application/x-moz-tabbrowser-tab"; var type1 = "text/x-moz-text-internal"; if (dt.types.contains(type0)) { newUrl(dt.getData(type1)); return true; } (略) // link && bookmarks var type = "text/x-moz-url"; if (dt.types.contains(type)) { var url = dt.getData("text/x-moz-url-data"); if (!url) newUrl(dt.getData("text/plain")); if (url) { newUrl(url); return true; } }
タブや、ブックマークからドラッグしたデータを application/x-moz-tabbrowser-tab、text/x-moz-text-internal、text/x-moz-url-data を使って判定しているんですね。
#bag iframe { -moz-transform-origin: 0% 0%; -moz-transform: scale(0.4); width: 625px; height: 625px; }
Webページは結局iframeを使って表示しています。
ここでCSS3のtransform: scaleを使ってオブジェクトを40%に縮小しているんですねぇ。
楽しみですね。HTML5。よりデスクトップアプリケーションの使い勝手に近づけそうです。
IEがどれだけ実装してくれるのかが普及の鍵ですかねぇ。
Comments:0
Trackback+Pingback:0
- TrackBack URL for this entry
- http://netforestdevnote.blog26.fc2.com/tb.php/36-4a0287f9
- Listed below are links to weblogs that reference
- HTML5 Drag and Drop APIとFile APIのデモ from Netforest Developer's Note