ゼロと無限の間に

フリーでオープンソースなJavaScriptとかPHPとか。

ユーザ用ツール

サイト用ツール


サイドバー

何かありましたら、メールで連絡いただくか、ブログのどこかにコメント入れてくださいね ^_^

Menu

ゼロと無限の間に

はじめに

作った主なサイト

作った主な便利ツール(無料)

ログ (Blog)

javascript:yahho-uploader

文書の過去の版を表示しています。


JavaScript 1ファイルでプログレスバー付きのファイルアップロードを実装 - Yahho Uploader

更新履歴とコメントはゼロと無限の間のログ » Yahho Uploaderでどうぞ。

The Yahoo! User Interface Library (YUI)を使いやすくラップするYahho!(ヤッホー)シリーズ。
Yahho Calendarに続く第2弾は、ファイルをアップロードしてアップロードの進捗を表すプログレスバーも表示するYahho Uploader。

必要なのはJavaScriptを1ファイルのみ。バックグラウンドではYUIのJavaScriptをいくつかとSWF(Flash)も使ってるけど、それらはYahoo!のサーバからロードできるので意識しないで済むはず。

サンプル

ライセンス

Yahho CalendarはMITライセンスで。
YUIの使用はYUIのライセンス(BSDライセンス)に従って。
米Yahoo!からYUIのファイルをロードする場合はServing YUI Files from Yahoo! Serversも要確認。

ダウンロード

使い方

  1. 下記の内容のXMLファイルを作成し、アップロード先のサーバのWebディレクトリのルートに“crossdomain.xml”という名前で保存する。(参考:Flashのドメイン間のデータロード許可) ただし、YUIのロードを自分のサーバからやる場合は不要。
    <?xml version="1.0"?>
    <cross-domain-policy>
    <allow-access-from domain="yui.yahooapis.com" />
    </cross-domain-policy>
  2. 後は下記の例を参考に、アップローダーを組み込む
    <!-- Yahho Uploaderを読み込む -->
    <script type="text/javascript" src="path/to/your/YahhoUpl.js"></script>
     
    <!-- Yahho Uploader設置の例 -->
    <script type="text/javascript">
    var yahho = new YahhoUpl();
     
    //やりたいアップロードに合わせて、好きなように設定する
    yahho.filterText = "画像ファイル";
    yahho.filterExtensions = ["jpg", "png", "gif"];
    yahho.maxCount = 5;
    yahho.maxSize = 50;
     
    //YUIをロードする。その際にコールバック関数を渡す(この代わりに静的ロードでもOK)
    YahhoUpl.loadYUI(setUpMyUploader);
     
    //コールバック関数。YUIのロードが完了したら呼ばれる
    function setUpMyUploader() {
      //プログレスバーを表示する場所のidと、アップロード先のURLを指定する
      yahho.setUp("progressBar", "http://example.com/your/uploade/url");
    }
    </script>
     
    <!-- ファイル選択のトリガーの例 -->
    <input type="button" value="Select File" onclick="yahho.browse()" />
     
    <!-- プログレスバーを表示する場所を作る -->
    <div id="progressBar"></div>

JavaScriptの書き方の例

こんな感じでも使える。

var yahho = new YahhoUpl();
 
//自分のサーバのyuiディレクトリからYUIをロードする場合
yahho.YUI_URL.SERVER = "";
yahho.YUI_URL.VERSION = "";
yahho.YUI_URL.DIR = "/yui/";
 
yahho.filterText = "どんなファイルでもいいよ";
yahho.filterExtensions = ["*"];
 
//アップロードと一緒にPOSTで渡すデータ
yahho.postVars = {foo: "bar", buz: 123};
 
yahho.onStart = function(){ alert("始まったよ!"); };
yahho.onComplete = function(id){ alert("1つ終わったよ"); };
yahho.onCompleteAll = function(){ alert("全部アップロードしたよ"); };
yahho.onError = function(id, httpStatus, errorInfo){ alert("エラーになっちゃった!><"); };
 
//FirefoxでAdblock Plusを使っている場合にyuiがフレームと勘違いして
//topを使おうとしてエラーになるのを回避する
var top = document;
 
YahhoUpl.loadYUI(function(){
  //自分のサーバ内で完結してれば、アップロード先のURLはドメイン無しでもいけると思う
  yahho.setUp("progressBar", "/distination.php");
});

ソースコード

/**
 *  Yahho Uploader
 *  @see http://0-oo.net/sbox/javascript/yahho-uploader
 *  @version 0.1.3
 *  @copyright 2008 dgbadmin@gmail.com
 *  @license http://0-oo.net/pryn/MIT_license.txt (The MIT license)
 */
 
/**
 *  コンストラクタ
 */
var YahhoUpl = function() {};
 
/**
 *  各種設定(やりたいことに合わせて上書きする)
 */
YahhoUpl.prototype = {
    /** YUIのURL(@see http://developer.yahoo.com/yui/articles/hosting/ ) */
    YUI_URL: {
        SERVER: "http://yui.yahooapis.com/",
        VERSION: "2.5.2",
        DIR: "/build/"
    },
 
    /** ファイル選択ダイアログで表示するファイル種類 */
    filterText: "JPEG画像",
 
    /** ファイル選択ダイアログで選択可能な拡張子 */
    filterExtensions: ["jpg", "jpeg"],
 
    /** ファイルをPOSTするフィールド名 */
    postKey: "Filedata",
 
    /** ファイルと一緒にPOSTするデータ */
    postVars: {},
 
    /** アップロード可能なファイル数 */
    maxCount: 1,
 
    /** 1ファイル当たりのファイルサイズ制限(単位はMB) */
    maxSize: 10,
 
    /**
     *  アップロード開始時のコールバック関数
     *  @param  Object  fileList    アップロードする全ファイルの情報
     */
    onStart: function(fileList) {},
 
    /**
     *  各ファイルごとのアップロード完了時のコールバック関数
     *  @param  String  id  ファイルID
     */
    onComplete: function(id) {},
 
    /**
     *  全各ファイルアップロード完了時のコールバック関数
     */
    onCompleteAll: function() {},
 
    /**
     *  アップロードエラー時のコールバック関数
     *  @param  String  id          ファイルID
     *  @param  Number  httpStatus  HTTPステータス
     *  @param  String  errorInfo   エラー情報
     */
    onError: function(id, httpStatus, errorInfo){
        alert("エラーが発生したためアップロードを中止しました。(" + httpStatus + ")");
    },
 
    /** プログレスバーのスタイル */
    progressBarStyle: {
        box: {padding: 0, width: "20em", height: "1em", backgroundColor: "#fff", border: "1px #000 solid"},
        bar: {margin: 0, height: "100%", backgroundColor: "#0f0", borderStyle: "none"}
    }
};
/**
 *  設定を取り込んでセットアップ
 *  @param  String  barId       プログレスバーのid属性
 *  @param  String  uploadUrl   アップロード先のURL(yui.yahooapis.comを使う場合はhttpから始まるURLを指定する)
 */
YahhoUpl.prototype.setUp = function(barId, uploadUrl) {
    var upl = this.getYUIUploader();
    this.upl = upl;
    var pBar = this.getProgressBar(barId);
    var bar = pBar.bar;
    var self = this;
 
    //ファイル選択時
    upl.addListener("fileSelect", function(ev) {
        self.totalSize = 0;
        var cnt = 0;
        for (var fileId in ev.fileList) {
            var size = ev.fileList[fileId].size;
            cnt++;
            if (cnt > self.maxCount) {
                alert("アップロードできるファイル数は " + self.maxCount + " ファイルまでです。");
                return;
            } else if (size / (1024 * 1024) > self.maxSize) {
                alert("アップロードできるファイルサイズは、1ファイルあたり " + self.maxSize + "MB までです。");
                return;
            }
            //プログレスバーのための準備
            ev.fileList[fileId].bytesLoaded = 0;
            self.totalSize += size;
        }
 
        //プログレスバー表示
        bar.style.width = "0%";
        pBar.box.style.display = "block";
 
        upl.uploadAll(uploadUrl, "POST", self.postVars, self.postKey);
        self.fileList = ev.fileList;
        self.onStart(ev.fileList);
        self.completeFlg = false;
    });
 
    //アップロード進行時
    upl.addListener("uploadProgress", function(ev) {
        self.letProgress(ev.id, ev.bytesLoaded, bar);
    });
 
    //アップロード完了時
    upl.addListener("uploadComplete", function(ev) {
        self.letProgress(ev.id, self.fileList[ev.id].size, bar);
        //コールバック
        self.onComplete(ev.id);
        if (bar.style.width == "100%" && !self.completeFlg) {
            self.completeFlg = true;
            self.onCompleteAll();
        }
    });
 
    //アップロードエラー時(1度のエラーで2回呼ばれる)
    upl.addListener("uploadError", function(ev) {
        if (isNaN(ev.status)) {    //2回目はエラー内容が渡される
            self.onError(ev.id, self.httpStatus, ev.status);
        } else {    //1回目はhttp statusが渡される
            self.httpStatus = ev.status;
        }
    });
};
/**
 *  アップローダー生成
 */
YahhoUpl.prototype.getYUIUploader = function() {
    //SWF用エリア(非表示)の生成
    var swfPlace = document.createElement("div");
    swfPlace.style.width = 0;
    swfPlace.style.height = 0;
    document.getElementsByTagName("body")[0].appendChild(swfPlace);
 
    //YUI Uploader生成
    var yuiBase = this.YUI_URL.SERVER + this.YUI_URL.VERSION + this.YUI_URL.DIR;
    YAHOO.widget.Uploader.SWFURL = yuiBase + "uploader/assets/uploader.swf";
    return new YAHOO.widget.Uploader(YAHOO.util.Dom.generateId(swfPlace));
};
/**
 *  プログレスバー生成
 */
YahhoUpl.prototype.getProgressBar = function(barId) {
    var box = document.getElementById(barId);
    box.style.display = "none";
    for (var style in this.progressBarStyle.box) {
        box.style[style] = this.progressBarStyle.box[style];
    }
    var bar = document.createElement("div");
    for (style in this.progressBarStyle.bar) {
        bar.style[style] = this.progressBarStyle.bar[style];
    }
    box.appendChild(bar);
    return {box: box, bar: bar};
};
/**
 *  プログレスバーを進める
 */
YahhoUpl.prototype.letProgress = function(eventId, amount, bar) {
    var list = this.fileList;
    list[eventId].bytesLoaded = amount;
    var loaded = 0;
    for (var fileId in list) {
        loaded += list[fileId].bytesLoaded;
    }
    bar.style.width = (loaded / this.totalSize) * 100 + "%";
};
/**
 *  ファイル選択&アップロード
 */
YahhoUpl.prototype.browse = function() {
    //ファイル選択フィルター作成
    var text = this.filterText + " (*." + this.filterExtensions.join(", *.") + ")";
    var ext = "*." + this.filterExtensions.join(";*.");
 
    try {
        this.upl.clearFileList();
        this.upl.browse((this.maxCount > 1), [{description: text, extensions: ext}]);
    } catch(e) {
        alert("アップロードするにはFlash Player(バージョン9.0.45以降)が必要です。");
    }
};
/**
 *  必要なYUIのファイルを読み込む
 *  @param  Function    callback    読み込み完了後に実行するコールバック関数
 */
YahhoUpl.loadYUI = function(callback) {
    var upl = new YahhoUpl();
    var yuiBase = upl.YUI_URL.SERVER + upl.YUI_URL.VERSION + upl.YUI_URL.DIR;
 
    //YUI Loaderをload
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = yuiBase + "yuiloader-dom-event/yuiloader-dom-event.js";
    document.getElementsByTagName("head")[0].appendChild(script);
 
    //YUI Loaderがloadされるまで待つ
    var limit = 3000, interval = 100, time = 0;
    var loadedId = setInterval(function(){
        if (window.YAHOO) {
            clearInterval(loadedId);
            //YUI Calendarをload
            new YAHOO.util.YUILoader({
                require: ["uploader"], base: yuiBase, onSuccess: callback
            }).insert();
        } else if ((time += interval) > limit) {    //タイムアウト
            alert("ファイルアップロード機能の読み込みに失敗しました。");
            clearInterval(loadedId);
        }
    }, interval);
};
javascript/yahho-uploader.1215524362.txt.gz · 最終更新: 2008/07/08 22:39 by dgbadmin