フォルダのドラッグ&ドロップアップを実現


ブラウザ上でフォルダを直接ドラッグ&ドロップして一括アップロードを実現する必要があります.
 
Html 5仕様はサポートされていませんが、chrome>=21ブラウザでサポートされています.
 
現在ファイルのドラッグアンドドロップアップにはjquery-filedropが採用されている.js https://github.com/weixiyen/jquery-filedropこのサポートされていないフォルダ
これを改善してフォルダをサポートできます.
 
元のコード:
   function drop(e) {
      if( opts.drop.call(this, e) === false ) return false;
      files = e.dataTransfer.files;
      if (files === null || files === undefined || files.length === 0) {
        opts.error(errors[0]);
        return false;
      }
      files_count = files.length;
      upload();
      e.preventDefault();
      return false;
    }

 
改善点は次のとおりです.
   function drop(e) {
      if( opts.drop.call(this, e) === false ) return false;

      function walkFileSystem(directory, callback, error) {
        if (!callback.pending) {
          callback.pending = 0;
        }
        if (!callback.files) {
          callback.files = [];
        }

        callback.pending++;

        var reader = directory.createReader(),
        relativePath = directory.fullPath.replace(/^\//, '').replace(/(.+?)\/?$/, '$1/');
        reader.readEntries(function(entries) {
          callback.pending--;
          $.each(entries, function(index, entry) {
            if (entry.isFile) {
              callback.pending++;
              entry.file(function(File) {
                File.path = encodeURIComponent(relativePath);
                callback.files.push(File);
                if (--callback.pending === 0) {
                    callback(callback.files);
                }
              }, error);
            } else {
              walkFileSystem(entry, callback, error);
            }
          });

          if (callback.pending === 0) {
            callback(callback.files);
          }
        }, error);
      }

      var items = e.dataTransfer.items || [], firstEntry;
        if (items[0] && items[0].webkitGetAsEntry && (firstEntry = items[0].webkitGetAsEntry())) {
          // Experimental way of uploading entire folders (only supported by chrome >= 21)
          walkFileSystem(firstEntry.filesystem.root, function(allfiles) {
            files = allfiles;
            files_count = files.length;
            upload();

          }, function() {
            // Fallback to old way when error happens
            files = e.dataTransfer.files;
            files_count = files.length;
            upload();
          });
        } else {
          files = e.dataTransfer.files;
          files_count = files.length;
          upload();
      }

      e.preventDefault();
      return false;
    }

 
上記の改善点の説明:
ブラウザがフォルダドラッグアンドドロップをサポートしている場合、タイプを判断し、フォルダであればフォルダディレクトリツリーを再帰的に読み取り、
すべてのファイルを見つけて、最後にアップロードします.
 
ディレクトリツリーでファイルを保存するにはどうすればいいですか?
 
実はフォルダを再帰的に読み込むとき、私はファイルにpath値を割り当てました.相対パスです.
これにより,サービス側はこのpathに基づいてディレクトリツリーごとの保存を実現できる.
 
他の箇所の修正点は一つ一つリストされず、修正後の完全なコードを添付します.