【问题标题】:drag'n'drop uploading images - support APIs issue拖放上传图片 - 支持 API 问题
【发布时间】:2013-08-21 09:14:06
【问题描述】:

我使用这个tutorial 作为指南来实现我自己的HTML5 拖放-上传功能。

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

我还在我的代码中包含了来自this 源代码的 sn-ps,以检查 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>

【问题讨论】:

    标签: html file-upload drag-and-drop xmlhttprequest


    【解决方案1】:

    问题

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

    解决方案

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

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

    • 将javascript放入script标签中,放在html下面。
    • 将 javascript 放入它自己的文件中,并将其 (&lt;script type="text/javascript" src="script.js"&gt;&lt;/script&gt;) 放在 html 下。
    • 将javascript放入函数中,然后将onload="functionName();"添加到body标签中。
    • 使用 jQuery 仅在文档​​“就绪”后运行代码,例如 $(document).ready(function () { //code goes here });
    • 还有很多其他我们现在还不需要深入研究的方法。

    让我们测试一下

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

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

    所以第 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'),恰好为 null。这意味着 javascript 找不到任何 id="filereader" 的元素。

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

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

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

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

    希望这会有所帮助:-)

    【讨论】:

    • 是的,谢谢,它有帮助。谢谢你的时间。惊人的分析器。好详细
    猜你喜欢
    • 2016-08-19
    • 1970-01-01
    • 2019-09-12
    • 2017-05-21
    • 2011-05-14
    • 2017-12-23
    • 2012-06-26
    • 2020-10-21
    • 1970-01-01
    相关资源
    最近更新 更多