HTML5 の File API を使った、OS からウェブ画面へのファイルドラッグ&ドロップを実現する方法を紹介します。
まず、何も準備しないでウェブ画面へファイルをドラッグ&ドロップすると、デフォルト挙動によって、そのファイルがブラウザで開かれます。例えば画像ファイルをウェブ画面にドラッグ&ドロップすると、その画像ファイルがブラウザ内で開かれて表示されます。
ドラッグ&ドロップを実現するには、まずブラウザのこのデフォルト挙動を上書きして、別の挙動にするよう指定する必要があります。そのためにファイルドロップのエリア(<div>)への drop イベントに対して、preventDefault(); を指定しておく必要があります。これでファイルをドロップしてもブラウザでは開かなくなります。
また、ドロップイベントのパラメータである event の event.dataTransfer.files プロパティにはドラッグ&ドロップしたファイルの情報が配列で入ってきます。このオブジェクトの内容が画像であるかどうかを調べた上で、画像と判別できたら Dynamic JavaScript を使って <img> タグを追加し、innerHTML でその画像を表示する、という挙動を実装しています。こうすることで動的に(リロードなしに)そのドロップされたファイルをブラウザ内に表示することができるようになります。
この挙動を実装したのが以下です。ピンクの枠(<div id="droparea">)がドラッグ&ドロップのドロップイベントを制御するエリアになっていて、この中に画像ファイルを(ドラッグ&)ドロップすると、その画像をリロードなしにその直下の <ul id="files"></ul> の中で表示します:
この HTML および JavaScript は以下になります:
参考にしたのはこちら:
http://jsfiddle.net/ginpei/bSF9z/
まず、何も準備しないでウェブ画面へファイルをドラッグ&ドロップすると、デフォルト挙動によって、そのファイルがブラウザで開かれます。例えば画像ファイルをウェブ画面にドラッグ&ドロップすると、その画像ファイルがブラウザ内で開かれて表示されます。
ドラッグ&ドロップを実現するには、まずブラウザのこのデフォルト挙動を上書きして、別の挙動にするよう指定する必要があります。そのためにファイルドロップのエリア(<div>)への drop イベントに対して、preventDefault(); を指定しておく必要があります。これでファイルをドロップしてもブラウザでは開かなくなります。
また、ドロップイベントのパラメータである event の event.dataTransfer.files プロパティにはドラッグ&ドロップしたファイルの情報が配列で入ってきます。このオブジェクトの内容が画像であるかどうかを調べた上で、画像と判別できたら Dynamic JavaScript を使って <img> タグを追加し、innerHTML でその画像を表示する、という挙動を実装しています。こうすることで動的に(リロードなしに)そのドロップされたファイルをブラウザ内に表示することができるようになります。
この挙動を実装したのが以下です。ピンクの枠(<div id="droparea">)がドラッグ&ドロップのドロップイベントを制御するエリアになっていて、この中に画像ファイルを(ドラッグ&)ドロップすると、その画像をリロードなしにその直下の <ul id="files"></ul> の中で表示します:
ここにファイルをドロップ
この HTML および JavaScript は以下になります:
<script type="text/javascript"> window.onload=function(){ var URL_BLANK_IMAGE = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'; var elDrop = document.getElementById('droparea'); var elFiles = document.getElementById('files'); elDrop.addEventListener('dragover', function(event) { event.preventDefault(); event.dataTransfer.dropEffect = 'copy'; showDropping(); }); elDrop.addEventListener('dragleave', function(event) { hideDropping(); }); elDrop.addEventListener('drop', function(event) { event.preventDefault(); hideDropping(); var files = event.dataTransfer.files; showFiles(files); }); document.addEventListener('click', function(event) { var elTarget = event.target; if (elTarget.tagName === 'IMG') { var src = elTarget.src; var w = window.open('about:blank'); var d = w.document; d.open(); d.write('<img src="' + src + '" />'); d.close(); } }); function showDropping() { elDrop.classList.add('dropover'); } function hideDropping() { elDrop.classList.remove('dropover'); } function showFiles(files) { elFiles.innerHTML = ''; for (var i=0, l=files.length; i<l; i++) { var file = files[i]; var elFile = buildElFile(file); elFiles.appendChild(elFile); } } function buildElFile(file) { var elFile = document.createElement('li'); if (file.type.indexOf('image/') === 0) { var elImage = document.createElement('img'); elImage.src = URL_BLANK_IMAGE; elFile.appendChild(elImage); attachImage(file, elImage); } return elFile; } function attachImage(file, elImage) { var reader = new FileReader(); reader.onload = function(event) { var src = event.target.result; elImage.src = src; elImage.setAttribute('title', file.name); }; reader.readAsDataURL(file); } } </script> <div effectallowed="move" id="droparea">ここにファイルをドロップ</div> <ul id="files"></ul>
参考にしたのはこちら:
http://jsfiddle.net/ginpei/bSF9z/