Jqueryを使ってHTML5ドラッグ&ドロップファイルアップロード

今のプロジェクトでドラッグ&ドロップでブラウザファイルアップロードの機能がいる。
検索してみたらたくさん方法が出てきます。その中一番いいと思うのはJqueryを使ってファイルアップロード。
とても勉強になりました、英語のページを翻訳して、ここに転載します。

原文はこちら

これに対してサーバー側のファイル保存について、下記リンクを参照してください。
phpサーバーアップロードファイル保存

*****以下は翻訳内容です*****

jQueryドラッグ&ドロップファイルアップロードの例で、HTML5およびjQuery AJAX APIを使用して、ドラッグ・アンド・ドロップ・ファイル・アップロードを実現する方法について説明しました。
ドラッグ&ドロップはHTML5をサポートするブラウザのみ使えます。
サポートされたブラウザは次のとおりです: IE 10+、Firefox、Chrome、Safari、Opera
live-demo
drag-and-drop-file-upload-jquery

上記のイメージで示されるようにドラッグ&ドロップファイルをアップロードさせるステップに従ってください。

ステップ1、jQueryライブラリをHTMLに引用

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>

ステップ2、divタグをアップロード処理したいの所に追加

<div id="dragandrophandler">ここにドロップしてください。</div>

アップロードのdivタグに下記のようなCSSを適用します。

#dragandrophandler
{
border:2px dotted #0B85A1;
width:500px;
color:#92AAB0;
text-align:left;vertical-align:middle;
padding:10px 10px 10 10px;
margin-bottom:10px;
font-size:200%;
}

ステップ3、jQueryでドラッグ&ドロップイベントをハンドル

var obj = $("#dragandrophandler");
obj.on('dragenter', function (e) 
{
    e.stopPropagation();
    e.preventDefault();
    $(this).css('border', '2px solid #0B85A1');
});
obj.on('dragover', function (e) 
{
     e.stopPropagation();
     e.preventDefault();
});
obj.on('drop', function (e) 
{
 
     $(this).css('border', '2px dotted #0B85A1');
     e.preventDefault();
     var files = e.originalEvent.dataTransfer.files;
 
     //We need to send dropped files to Server
     handleFileUpload(files,obj);
});

ファイルがdivの外でドロップされた場合、ブラウザで開いてしまいます。それを避けるため、documentの「ドロップ」イベントを防ぐ。

$(document).on('dragenter', function (e) 
{
    e.stopPropagation();
    e.preventDefault();
});
$(document).on('dragover', function (e) 
{
  e.stopPropagation();
  e.preventDefault();
  obj.css('border', '2px dotted #0B85A1');
});
$(document).on('drop', function (e) 
{
    e.stopPropagation();
    e.preventDefault();
});

ステップ4、ファイルがドロップされた時に、HTML5のFormData()を使って、ファイルの中身を読み

function handleFileUpload(files,obj)
{
   for (var i = 0; i < files.length; i++) 
   {
        var fd = new FormData();
        fd.append('file', files[i]);
 
        var status = new createStatusbar(obj); //Using this we can set progress.
        status.setFileNameSize(files[i].name,files[i].size);
        sendFileToServer(fd,status);
 
   }
}

ステップ5、jQuery AJAX APIを使って、FormData()をサーバーに送信

function sendFileToServer(formData,status)
{
    var uploadURL ="http://hayageek.com/examples/jquery/drag-drop-file-upload/upload.php"; //Upload URL
    var extraData ={}; //Extra Data.
    var jqXHR=$.ajax({
            xhr: function() {
            var xhrobj = $.ajaxSettings.xhr();
            if (xhrobj.upload) {
                    xhrobj.upload.addEventListener('progress', function(event) {
                        var percent = 0;
                        var position = event.loaded || event.position;
                        var total = event.total;
                        if (event.lengthComputable) {
                            percent = Math.ceil(position / total * 100);
                        }
                        //Set progress
                        status.setProgress(percent);
                    }, false);
                }
            return xhrobj;
        },
        url: uploadURL,
        type: "POST",
        contentType:false,
        processData: false,
        cache: false,
        data: formData,
        success: function(data){
            status.setProgress(100);
 
            //$("#status1").append("File upload Done<br>");           
        }
    }); 
 
    status.setAbort(jqXHR);
}

まとめる

以上ステップのソースを纏めって、ドラッグ&ドロップファイルアップロードのサンプルは下記のようになります。

<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<style>
#dragandrophandler
{
border:2px dotted #0B85A1;
width:500px;
color:#92AAB0;
text-align:left;vertical-align:middle;
padding:10px 10px 10 10px;
margin-bottom:10px;
font-size:200%;
}
.progressBar {
    width: 200px;
    height: 22px;
    border: 1px solid #ddd;
    border-radius: 5px; 
    overflow: hidden;
    display:inline-block;
    margin:0px 10px 5px 5px;
    vertical-align:top;
}
 
.progressBar div {
    height: 100%;
    color: #fff;
    text-align: right;
    line-height: 22px; /* same as #progressBar height if we want text middle aligned */
    width: 0;
    background-color: #0ba1b5; border-radius: 3px; 
}
.statusbar
{
    border-top:1px solid #A9CCD1;
    min-height:25px;
    width:700px;
    padding:10px 10px 0px 10px;
    vertical-align:top;
}
.statusbar:nth-child(odd){
    background:#EBEFF0;
}
.filename
{
display:inline-block;
vertical-align:top;
width:250px;
}
.filesize
{
display:inline-block;
vertical-align:top;
color:#30693D;
width:100px;
margin-left:10px;
margin-right:5px;
}
.abort{
    background-color:#A8352F;
    -moz-border-radius:4px;
    -webkit-border-radius:4px;
    border-radius:4px;display:inline-block;
    color:#fff;
    font-family:arial;font-size:13px;font-weight:normal;
    padding:4px 15px;
    cursor:pointer;
    vertical-align:top
    }
</style>
</head>
 
<body>
<div id="dragandrophandler">ここにドロップしてください。</div>
<br><br>
<div id="status1"></div>
<script>
function sendFileToServer(formData,status)
{
    var uploadURL ="http://hayageek.com/examples/jquery/drag-drop-file-upload/upload.php"; //Upload URL
    var extraData ={}; //Extra Data.
    var jqXHR=$.ajax({
            xhr: function() {
            var xhrobj = $.ajaxSettings.xhr();
            if (xhrobj.upload) {
                    xhrobj.upload.addEventListener('progress', function(event) {
                        var percent = 0;
                        var position = event.loaded || event.position;
                        var total = event.total;
                        if (event.lengthComputable) {
                            percent = Math.ceil(position / total * 100);
                        }
                        //Set progress
                        status.setProgress(percent);
                    }, false);
                }
            return xhrobj;
        },
    url: uploadURL,
    type: "POST",
    contentType:false,
    processData: false,
        cache: false,
        data: formData,
        success: function(data){
            status.setProgress(100);
 
            $("#status1").append("File upload Done<br>");         
        }
    }); 
 
    status.setAbort(jqXHR);
}
 
var rowCount=0;
function createStatusbar(obj)
{
     rowCount++;
     var row="odd";
     if(rowCount %2 ==0) row ="even";
     this.statusbar = $("<div class='statusbar "+row+"'></div>");
     this.filename = $("<div class='filename'></div>").appendTo(this.statusbar);
     this.size = $("<div class='filesize'></div>").appendTo(this.statusbar);
     this.progressBar = $("<div class='progressBar'><div></div></div>").appendTo(this.statusbar);
     this.abort = $("<div class='abort'>Abort</div>").appendTo(this.statusbar);
     obj.after(this.statusbar);
 
    this.setFileNameSize = function(name,size)
    {
        var sizeStr="";
        var sizeKB = size/1024;
        if(parseInt(sizeKB) > 1024)
        {
            var sizeMB = sizeKB/1024;
            sizeStr = sizeMB.toFixed(2)+" MB";
        }
        else
        {
            sizeStr = sizeKB.toFixed(2)+" KB";
        }
 
        this.filename.html(name);
        this.size.html(sizeStr);
    }
    this.setProgress = function(progress)
    {       
        var progressBarWidth =progress*this.progressBar.width()/ 100;  
        this.progressBar.find('div').animate({ width: progressBarWidth }, 10).html(progress + "% ");
        if(parseInt(progress) >= 100)
        {
            this.abort.hide();
        }
    }
    this.setAbort = function(jqxhr)
    {
        var sb = this.statusbar;
        this.abort.click(function()
        {
            jqxhr.abort();
            sb.hide();
        });
    }
}
function handleFileUpload(files,obj)
{
   for (var i = 0; i < files.length; i++) 
   {
        var fd = new FormData();
        fd.append('file', files[i]);
 
        var status = new createStatusbar(obj); //Using this we can set progress.
        status.setFileNameSize(files[i].name,files[i].size);
        sendFileToServer(fd,status);
 
   }
}
$(document).ready(function()
{
var obj = $("#dragandrophandler");
obj.on('dragenter', function (e) 
{
    e.stopPropagation();
    e.preventDefault();
    $(this).css('border', '2px solid #0B85A1');
});
obj.on('dragover', function (e) 
{
     e.stopPropagation();
     e.preventDefault();
});
obj.on('drop', function (e) 
{
 
     $(this).css('border', '2px dotted #0B85A1');
     e.preventDefault();
     var files = e.originalEvent.dataTransfer.files;
 
     //We need to send dropped files to Server
     handleFileUpload(files,obj);
});
$(document).on('dragenter', function (e) 
{
    e.stopPropagation();
    e.preventDefault();
});
$(document).on('dragover', function (e) 
{
  e.stopPropagation();
  e.preventDefault();
  obj.css('border', '2px dotted #0B85A1');
});
$(document).on('drop', function (e) 
{
    e.stopPropagation();
    e.preventDefault();
});
 
});
</script>
</body>
</html>

jQuery UIのインストールと使い方紹介

jQuery UIjQueryを基に構築された公式JavaScriptのライブラリです。
マウスベースのインタラクションやアニメーション、テーマを適用可能なダイアログや日付Datepickerといったウィジェットが提供される。
jQuery UIを利用して、簡単に機能豊富のウェブページを作れます。

オフライン利用

オフライン利用のため、ローカルにダウンロードが必要です。
ここからダウンロードします。
バージョンと使う機能、及びテーマを選べます。
jqueryui-intro1
jqueryui-intro2
jQuery UIはいろいろテーマを提供しています。
http://jqueryui.com/themeroller/
jqueryui-intro3

ダウンロードしたファイルを引用します。
jQueryベースですので、jQueryの引用も必要です。

<!--jQuery-->
<script src="js/jquery-1.10.2.js"></script>
<!--jQuery UI-->
<script src="js/jquery-ui-1.10.4.js"></script>
<!--jQuery UI theme-->
<link rel="stylesheet" href="css/ui-lightness/jquery-ui-1.10.4.custom.css" type="text/css" />

オンライン

jQueryとjQuery UI両方ともダウンロードせず、直接URL引用してオンラインで使えます。

<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/redmond/jquery-ui.min.css" type="text/css" />

オンラインもいろいろテーマを使えます。使えるテーマを纏めます。代表的なカレンダーで配色パターンを例とします。

Black Tie

http://code.jquery.com/ui/1.10.3/themes/black-tie/jquery-ui.min.css

jqueryui-theme-BlackTie
Blitzer

http://code.jquery.com/ui/1.10.3/themes/blitzer/jquery-ui.min.css

jqueryui-theme-Blitzer
Cupertino

http://code.jquery.com/ui/1.10.3/themes/cupertino/jquery-ui.min.css

jqueryui-theme-Cupertino
Dark Hive

http://code.jquery.com/ui/1.10.3/themes/dark-hive/jquery-ui.min.css

jqueryui-theme-DarkHive
Dot luv

http://code.jquery.com/ui/1.10.3/themes/dot-luv/jquery-ui.min.css

jqueryui-theme-DotLuv
Eggplant

http://code.jquery.com/ui/1.10.3/themes/eggplant/jquery-ui.min.css

jqueryui-theme-Eggplant
Flick

http://code.jquery.com/ui/1.10.3/themes/flick/jquery-ui.min.css

jqueryui-theme-flick
Hot Sneaks

http://code.jquery.com/ui/1.10.3/themes/hot-sneaks/jquery-ui.min.css

jqueryui-theme-hotSneaks
Humanity

http://code.jquery.com/ui/1.10.3/themes/humanity/jquery-ui.min.css

jqueryui-theme-Humanity
Le frog

http://code.jquery.com/ui/1.10.3/themes/le-frog/jquery-ui.min.css

jqueryui-theme-lefrog
Mint choc

http://code.jquery.com/ui/1.10.3/themes/mint-choc/jquery-ui.min.css

jqueryui-theme-MintChoc
Overcast

http://code.jquery.com/ui/1.10.3/themes/overcast/jquery-ui.min.css

jqueryui-theme-overcast
Pepper ginder

http://code.jquery.com/ui/1.10.3/themes/pepper-grinder/jquery-ui.min.css

jqueryui-theme-peppergrinder
Redmond

http://code.jquery.com/ui/1.10.3/themes/redmond/jquery-ui.min.css

jqueryui-theme-redmond
Smoothness

http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.min.css

jqueryui-theme-smoothness
South street

http://code.jquery.com/ui/1.10.3/themes/south-street/jquery-ui.min.css

jqueryui-theme-SouthStreet
Start

http://code.jquery.com/ui/1.10.3/themes/start/jquery-ui.min.css

jqueryui-theme-start
Sunny

http://code.jquery.com/ui/1.10.3/themes/sunny/jquery-ui.min.css

jqueryui-theme-sunny
Swanky purse

http://code.jquery.com/ui/1.10.3/themes/swanky-purse/jquery-ui.min.css

jqueryui-theme-SwankyPurse
Excite bike

http://code.jquery.com/ui/1.10.3/themes/excite-bike/jquery-ui.min.css

jqueryui-theme-ExciteBike
Trontastic

http://code.jquery.com/ui/1.10.3/themes/trontastic/jquery-ui.min.css

jqueryui-theme-Trontastic
ui-lightness

http://code.jquery.com/ui/1.10.3/themes/ui-lightness/jquery-ui.min.css

ui-lightness
ui-darkness

http://code.jquery.com/ui/1.10.3/themes/ui-darkness/jquery-ui.min.css

jqueryui-theme-uidarkness
Vader

http://code.jquery.com/ui/1.10.3/themes/vader/jquery-ui.min.css

jqueryui-theme-Vader

機能&使い方

1.タブメニューの作成
jquery-ui-tabs-normal

jQuery UIを使ってタブメニューを作成

基本のJavaScriptとCSSだけでタブメニューを作成のは大変面倒くさいです。
jQuery UIを利用して、簡単にタブメニューを作成の方法を紹介します。
シンプルのタブから、いろいろカスタマイズも説明します。

jQueryとjQuery UIのインストールはここを参照してください。

1、基本のタブメニューを作成

先ず、こんな形HTMLを準備してください。作成したいタブ数で<li>タグを書きます。
各<li>に対応する<div>も書きます。
<a>の属性hrefの値と<div>のidが一致しないといけないことを注意してください。

<div id="tabs">
  <ul>
    <li><a href="#tabs-1">日本酒</a></li>
    <li><a href="#tabs-2">焼酎</a></li>
    <li><a href="#tabs-3">ビール</a></li>
  </ul>
  <div id="tabs-1">
    <p>・獺祭<br/>・十四代<br/>・久保田</p>
  </div>
  <div id="tabs-2">
    <p>・佐藤<br/>・魔王<br/>・百年の孤独</p>
  </div>
  <div id="tabs-3">
    <p>・朝日<br/>・YEBISU<br/>・麒麟</p>
  </div>
</div>

tabs()函数をコールして、タブを生成します。
HTMLロード時にタブ生成するため下記JavaScriptを実行させます。

$("#tabs").tabs();

これで、タブメニューが生成されました。

jquery-ui-tabs-normal
jQueryUIで作成したタブ

2、折り畳めるタブを作成

tabs()函数を使用時に、オプションがサポートされます。
collapsible: trueを指定して、折り畳めるタブを作成できます。

$("#tabs").tabs({
collapsible: true
});

タブメニューを二度クリックしてタブの折り畳みと展開の切替できます。

3、マウスオーバーでタブを切替

デフォルトはクリックでタブを切替する。
event: “mouseover”を指定して、マウスオーバーでタブを切替になります。

$("#tabs").tabs({
event: "mouseover"
});

4、順番が変えれるタブメニュー

マウスでタブをドラッグ&ドロップしてタブの順番を変えます。

var tabs = $( "#tabs" ).tabs();
tabs.find( ".ui-tabs-nav" ).sortable({
  axis: "x",
  stop: function() {
	tabs.tabs( "refresh" );
  }
});

5、タブメニューを底部表示

タブメニューを中身の底部で表示させます。
JavaScriptでDOMを操作します。
タブのクラス(ui-tabs-nav)でタブを取得してappendToを使って底部に移動します。
これだけタブの丸角は上のままになっていますので、ui-corner-bottomのクラスを追加して丸角を底部に変更します。
JavaScriptはこんな感じです。

$( "#tabs" ).tabs();
// classでタブを探す、上の丸角を直角に、下の直角を丸角に変更する
$( "#tabs .ui-tabs-nav, #tabs .ui-tabs-nav > *" )
  .removeClass( "ui-corner-all ui-corner-top" )
  .addClass( "ui-corner-bottom" );
// タブを下に移動する
$( "#tabs .ui-tabs-nav" ).appendTo( "#tabs" );

出来ました!

jquery-ui-tabs-buttom
タブを底部表示

6、横でタブメニューを表示

ちょっと工夫します、CSSで横メニューの仕様を調整します。

<style>
  .ui-tabs-vertical { width: 55em; }
  .ui-tabs-vertical .ui-tabs-nav { padding: .2em .1em .2em .2em; float: left; width: 12em; }
  .ui-tabs-vertical .ui-tabs-nav li { clear: left; width: 100%; border-bottom-width: 1px !important; border-right-width: 0 !important; margin: 0 -1px .2em 0; }
  .ui-tabs-vertical .ui-tabs-nav li a { display:block; }
  .ui-tabs-vertical .ui-tabs-nav li.ui-tabs-active { padding-bottom: 0; padding-right: .1em; border-right-width: 1px; border-right-width: 1px; }
  .ui-tabs-vertical .ui-tabs-panel { padding: 1em; float: right; width: 40em;}
</style>

javascriptでタブにclassを追加します

$( "#tabs" ).tabs().addClass( "ui-tabs-vertical ui-helper-clearfix" );
$( "#tabs li" ).removeClass( "ui-corner-top" ).addClass( "ui-corner-left" );

出来たタブはこんな感じです。

jquery-ui-tabs-left
タブを横で表示

以上、jQueryUIを利用して、タブの作り方です。

HTML5のcanvasを使って映画「マトリックス」の文字落ちてくるかっこいい効果を実現

映画「マトリックス」の超かっこいいのシーン、ブラックのグランドで緑の文字は雨みたい落ちる、覚えていますか。
今日はHTML5のcanvasを使って、その効果を再現します。
効果はこちら↓

全画面表示はこちらです。

ソースは下記です。

<canvas id="q"></canvas>
<script type="text/javascript"> 
var s = window.screen; 
var width = q.width = s.width; 
var height = q.height = s.height; 
var letters = Array(256).join(1).split(''); 
var draw = function () { 
q.getContext('2d').fillStyle='rgba(0,0,0,.05)'; 
q.getContext('2d').fillRect(0,0,width,height); 
q.getContext('2d').fillStyle='#0F0'; 
letters.map(function(y_pos, index){ 
text = String.fromCharCode(3e4+Math.random()*33); 
x_pos = index * 10; 
q.getContext('2d').fillText(text, x_pos, y_pos); 
letters[index] = (y_pos > 758 + Math.random() * 1e4) ? 0 : y_pos + 10; 
}); 
}; 
setInterval(draw, 33); 
</script>

面白いと思ったら是非やってみてください。

wordpressの投稿記事内に直接JavaScriptを使用

wordpressの投稿記事内で直接JavaScriptを記述したところ、動作できないことを分かりました。

いろいろ調べました。
プラグインを利用すれば、JavaScriptを使えるが、プラグインをたくさんインストールするとページのロード時間が落ちます。

プラグイン以外、直接JavaScriptを使用の方法もあります。
divタグを使って、scriptを囲む
サンプル:

<div>
<script type="text/javascript">;
function hello(){
    alert("Hello world!");
}
</script>
</div>

一つ注意点があります。
scriptタグ内にJavascriptのソースは空行を含めないことです

以上、WordPressの記事に直接JavaScriptを書いて動作させる方法です。
お役に立てたら嬉しいです。