0

我使用本教程作为实现我自己的 HTML5 拖放上传功能的指南。

我还使用 File API、FileReader API 和 XHR2 API

我还在我的代码中包含了这个源代码的片段,以检查 API 支持。

奇怪的是,我用实际上支持 XHR2 和 File API 的 Chrome 28.0.1 和 Firefox 23.0.1 打开文件,我得到了

File API & FileReader API not supported

XHR2's FormData is not supported

XHR2's upload progress isn't supported

我不明白出了什么问题。我是这些 API 的新手。产生语法错误是一回事,但不支持 API?他们应该在哪里?我只是不明白。

谢谢你的时间

这是我的代码

    <style>
    #holder { border: 10px dashed #ccc; width: 300px; min-height: 300px; margin: 20px auto;}
    #holder.hover { border: 10px dashed #0c0; }
    #holder img { display: block; margin: 10px auto; }
    #holder p { margin: 10px; font-size: 14px; }
    progress { width: 100%; }
    progress:after { content: '%'; }
    .fail { background: #c00; padding: 2px; color: #fff; }
    .hidden { display: none !important;}
    </style>


    <script type='text/javascript'>
//check for support API
    var holder = document.getElementById('holder'),
         tests = {
          filereader: typeof FileReader != 'undefined',
          dnd: 'draggable' in document.createElement('span'),
          formdata: !!window.FormData,
          progress: "upload" in new XMLHttpRequest
        }, 
        support = {
          filereader: document.getElementById('filereader'),
          formdata: document.getElementById('formdata'),
          progress: document.getElementById('progress')
        },
        acceptedTypes = {
          'image/png': true,
          'image/jpeg': true,
          'image/gif': true
        },
        progress = document.getElementById('uploadprogress'),
        fileupload = document.getElementById('upload');

    "filereader formdata progress".split(' ').forEach(function (api) {
      if (tests[api] === false) {
          alert('inside me, bad...');
        support[api].className = 'fail';
      } else {
        // FFS. I could have done el.hidden = true, but IE doesn't support
        // hidden, so I tried to create a polyfill that would extend the
        // Element.prototype, but then IE10 doesn't even give me access
        // to the Element object. Brilliant.
        support[api].className = 'hidden';
      }
    });

//preview files/images-give feedback to user
    function previewfile(file) {
      if (tests.filereader === true && acceptedTypes[file.type] === true) {
        var reader = new FileReader();
        reader.onload = function (event) {
          var image = new Image();
          image.src = event.target.result;
          image.width = 250; // a fake resize
          holder.appendChild(image);
        };

        reader.readAsDataURL(file);
      }  else {
        holder.innerHTML += '<p>Uploaded ' + file.name + ' ' + (file.size ? (file.size/1024|0) + 'K' : '');
        alert(file.name);
        console.log(file);
      }
    }

    //read file from drop area
    function readfiles(files) {
        debugger;
        var formData = tests.formdata ? new FormData() : null;
        for (var i = 0; i < files.length; i++) {
          if (tests.formdata) formData.append('file', files[i]);
          alert(files[i].name);
          previewfile(files[i]);
        }

        // now send file
        if (tests.formdata) {
          var xhr = new XMLHttpRequest();
          xhr.open('POST', '/upload.php');
          xhr.onload = function() {
            progress.value = progress.innerHTML = 100;
          };

          if (tests.progress) {
            xhr.upload.onprogress = function (event) {
              if (event.lengthComputable) {
                var complete = (event.loaded / event.total * 100 | 0);
                progress.value = progress.innerHTML = complete;
              }
            }
          }

          xhr.send(formData);
        }
    }

    if (tests.dnd) { 

       holder.addEventListener('drop', ondrop, false); 
       holder.addEventListener('dragover', ondragover, false); 
       holder.addEventListener('dragend', ondragend, false); 

      holder.ondragover = function () { this.className = 'hover'; return false; };
      holder.ondragend = function () { this.className = ''; return false; };
      holder.ondrop = function (e) {
        this.className = '';
        e.preventDefault();
        readfiles(e.dataTransfer.files);
      }
    } else {
      fileupload.className = 'hidden';
      fileupload.querySelector('input').onchange = function () {
        readfiles(this.files);
      };
    }

    </script>


    <!-- the html -->
     <div id="holder">
      </div> 

      <p id="upload" class="hidden"><label>Drag &amp; drop not supported, but you can still upload via this input field:<br><input type="file"></label></p>
      <p id="filereader">File API &amp; FileReader API not supported</p>
      <p id="formdata">XHR2's FormData is not supported</p>
      <p id="progress">XHR2's upload progress isn't supported</p>
      <p>Upload progress: <progress id="uploadprogress" min="0" max="100" value="0">0</progress></p>
      <p>Drag an image from your desktop on to the drop zone above to see the browser both render the preview, but also upload automatically to this server.</p>
4

1 回答 1

3

问题

基本上,javascript 正在尝试访问尚不存在的 html。

解决方案

这可以通过在加载 html 后运行 javascript 来解决。

有很多方法可以做到这一点:

  • 将javascript放入脚本标签并放置在html下。
  • 将 javascript 放入它自己的文件中,并将它 ( <script type="text/javascript" src="script.js"></script>) 放在 html 下。
  • 将 javascript 放入一个函数中,然后添加onload="functionName();"到 body 标记中。
  • 使用 jQuery 仅在文档​​“准备好”后运行代码,例如$(document).ready(function () { //code goes here });
  • 许多其他的方式,我们还没有真正需要进入。

让我们测试一下以确保

您提供的代码给出了这个错误TypeError: support[api] is null on line 44

为了快速测试,我console.log('api',api);在第 44 行添加了这个。

所以第 44 和 45 行看起来像这样:

console.log('api',api);
support[api].className = 'hidden';

控制台日志输出:

api filereader
TypeError: support[api] is null

再看代码,我们可以看到support[filereader]在第 23 行设置

support = {
          filereader: document.getElementById('filereader'),

所以 api = document.getElementById('filereader') 恰好为空。这意味着 javascript 找不到任何 id="filereader" 的元素。

但是我们通过查看第 126 行就知道它的存在

<p id="filereader">File API &amp; FileReader API not supported</p>

所以也许 javascript 无法访问它,因为它已经加载到页面上。

让我们尝试将 javascript 放在 html 下方......现在它可以工作了!

希望这可以帮助 :-)

于 2013-08-24T16:02:32.383 回答