1

こんにちは、Chrome を使用してファイルをファイル システムにドラッグ アンド ドロップしようとしていますが、コンソールに次のエラーが表示されます。

var dnd = new DnDFileController('body', function(files, e) {
    var items = e.dataTransfer.items;
    for (var i = 0, item; item = items[i]; ++i) {
      traverseFileTree(item.webkitGetAsEntry());
**Uncaught TypeError: Object #<DataTransferItem> has no method 'webkitGetAsEntry'**
    }
  });

私はまた、次のようにループにメソッドを追加しようとしました:

for (var i = 0, item; item = items[i].webkitGetAsEntry();; ++i) {
      traverseFileTree(item);
    }

エラーは次のようになります。

Uncaught TypeError: Object #<DataTransferItem> has no method 'webkitGetAsEntry' app.js:513
(anonymous function) app.js:513
DnDFileController.drop dnd.js:27

DNDFileController.drop コードは次のとおりです。

this.drop = function(e) {
    e.stopPropagation();
    e.preventDefault();

    el_.classList.remove('dropping');

    onDropCallback(e.dataTransfer.files, e);
  };

しかし、同じエラーが発生します。アイデアはありますか? ありがとう。

4

1 に答える 1

8

おそらく、この DnDFileController - http://html5-demos.appspot.com/static/filesystem/filer.js/demos/js/dnd.jsを使用しています。まず、コードを次のようにテスト可能な状態にしました。

function DnDFileController(selector, onDropCallback) {
  var el_ = document.querySelector(selector);

  this.dragenter = function(e) {
    e.stopPropagation();
    e.preventDefault();
    el_.classList.add('dropping');
  };

  this.dragover = function(e) {
    e.stopPropagation();
    e.preventDefault();
  };

  this.dragleave = function(e) {
    e.stopPropagation();
    e.preventDefault();
    //el_.classList.remove('dropping');
  };

  this.drop = function(e) {
    e.stopPropagation();
    e.preventDefault();

    el_.classList.remove('dropping');
    onDropCallback(e.dataTransfer.files, e);
  };

  el_.addEventListener('dragenter', this.dragenter, false);
  el_.addEventListener('dragover', this.dragover, false);
  el_.addEventListener('dragleave', this.dragleave, false);
  el_.addEventListener('drop', this.drop, false);
};

var dnd = new DnDFileController('body', function(files, e) {
    var items = e.dataTransfer.items;
    for (var i = 0, item; item = items[i]; ++i) {
      if (item.kind == 'file') {
          debugger
          console.log(item.webkitGetAsEntry());
      }
    }
  });

現在、Chrome 20.0.1132.27 ベータ版のデバッガーでアイテムの状態を確認すると、現在の仕様 [1] にあるプロパティとメソッドのみが公開されています - つまり、item.kind、item.type、item.getAsString( callback)、および item.getAsFile()。DataTransferItem.webkitGetAsEntry() は公開されていません。私が知る限り [2]、Chrome は彼らが提案した webkitGetAsEntry をまだ公開することになっておらず、わずか 1 週間オンにした後 [3]、スイッチをオフに戻しました。したがって、現時点では、フラグを使用して有効にしない限り有効になりません[4]。

有効にすると、getAsString のように、getter としてだけでなく、コールバックで使用することも意図されているように見えます。[5] の例を参照してください。

    var items = e.dataTransfer.items;
    for (var i = 0; i < items.length; ++i) {
      if (items[i].kind == 'file') {
          items[i].webkitGetAsEntry(function(entry) {
          displayEntry(entry.name + (entry.isDirectory ? ' [dir]' : ''));
          ...
        });
      }
    }

また、file[i] が実際にはファイルであるという保護チェックでラップしていることにも注意してください。これは上記のテスト コードにありますが、コードにはありません。

しかし、ファイルにアクセスしようとしているだけなら、この実験的な方法を使用したい理由はありますか? FileReader を使用してファイルを読み取り、Blob 化してローカルの FileSystem に保存するのは非常に単純なループです。

参照:

[1] http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#the-datatransferitem-interface

[2] http://trac.webkit.org/changeset/118507

[3] http://code.google.com/p/chromium/issues/detail?id=129702

[4] https://bugs.webkit.org/show_bug.cgi?id=87457

[5] http://lists.w3.org/Archives/Public/public-whatwg-archive/2012Apr/0078.html

================================================== ====

2012 年 7 月 26 日更新:

このメソッドは現在、フラグの要件が削除されており、2012 年 7 月 23 日の Chrome 21 のリリースで一般的に使用できるようになりました。ただし、ここで説明する使用例では、ディレクトリ全体を同時に読み取る必要がないため、上記の方が実装がはるかに簡単で、ニーズにより適しています。

于 2012-07-13T21:05:21.693 に答える