0

我一直在尝试以动态加载的格式实现一些文件上传器包(原始 php),页面上的数量可能未知。我几乎看过所有流行的,从基于闪存的到介于两者之间的所有东西,但有同样的问题。

我目前正在尝试使用这个

我已经尝试过我读过的技巧,比如使用^=ingetelementbyid以及"\\S*"确保 javascript 使用相关的 div id,但我没有成功。我还尝试为每个 div 添加一个类名并使用 getelementbyclass 没有成功。我已经到处寻找解决方案,但我就是不明白。

要么我做错了,要么我完全迷失了......我实际上都是!

如果有人能让我摆脱痛苦或让我朝着正确的方向前进,我将非常感激,因为我一直在努力寻找解决方案。

HTML 部分如下所示:

<p id="upload" class="hidden"><label>Drag & drop not supported, but you can still upload via this input field:<br><input type="file"></label></p>
  <p id="filereader">File API & 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>

我打算通过 PHP 动态生成它,其中 $inc 是循环中的 php 变量,例如 id="filereader$inc

我相信这个问题是javascript只会处理上传者的预定义或一个实例,直到以其他方式修改

例如:文件阅读器:document.getElementById('filereader')

4

2 回答 2

0

该Javascript代码不适用于多个实例,因为它使用getElementById仅返回一个元素(它找到的第一个匹配项)的方法。

还值得一提的是,JS 代码不适用于许多用户(我相信大约有一半),因为它依赖于 IE9 及以下不支持的 File API。

要使该代码适用于多个实例,必须对其进行重构以便不依赖元素 ID,或者您必须使用服务器端代码生成具有唯一元素 ID 的多个副本。在 PHP 中,这将涉及使用类似这样的foror循环:foreach

<?php

for (i=0; $i<$something; i++) {
  echo <<<EOB
  var holder = document.getElementById('holder$i'),
    tests = {
    filereader: typeof FileReader != 'undefined',   
    dnd: 'draggable' in document.createElement('span'),
    formdata: !!window.FormData,
    progress: "upload" in new XMLHttpRequest
    }, 
    support = {
    filereader: document.getElementById('filereader$i'),
    formdata: document.getElementById('formdata$i'),
    progress: document.getElementById('progress$i')
    },
// snipped for space
EOB;
}

我不推荐任何一种做法,主要是因为它仍然无法与大量用户一起使用。相反,我建议使用不同的上传库。

我对 JS 文件上传库同样不满意,所以我写了一个支持 IE7+(理论上是 IE6,但未经测试)、进度条(带有处理 IE9 及以下版本的回退选项)并允许多个实例的库。

但是,它不支持拖放上传,所以如果这是一个要求,它将不适合您的需求。对于它的价值,这里是(链接到顶部的现场演示):

https://github.com/LPology/Simple-Ajax-Uploader

于 2013-04-07T11:10:42.303 回答
0

好的,如果我理解正确,您想在页面的不同部分使用拖放字段。

所以简短的回答是,您必须将事件添加到每个应该具有此功能的 div 中。由于上传是自动进行的,您只需要一个文件输入字段

只有 dropzones 必须被复制(但只有在你想要的时候,更多的 dropzone)并且它们的偶数必须被调整

Ps.:html部分与博客中的相同(加上id为holder的div [和第二个dropzone的holder2],似乎已被省略)

例子:

// tested on Chrome 26+
....
if (tests.dnd) { 
  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);
  }
  //.... other drop spots example need the same events ....
  holder2.ondragover = function () { this.className = 'hover'; return false; };
  holder2.ondragend = function () { this.className = ''; return false; };
  holder2.ondrop = function (e) {
      this.className = '';
      e.preventDefault();
      readfiles(e.dataTransfer.files);
  }
} else {
 ...
}
...

这行得通,但你可以使用 jQuery 左右让它变得更好。

我希望它有帮助

编辑: 如果您想将文件发送到不同的服务器端脚本,您必须在 te onDrop 事件中“修改”函数readfiles

示例(可能的解决方案,不是很干净):

// tested on Chrome 26+
 ....
 holder.ondrop = function (e) {
  this.className = '';
  e.preventDefault();
  readfiles(e.dataTransfer.files, "script_1.php");
  }
 ...
 function readfiles(files, posturl) {
 ...
   // now post a new XHR request
  if (tests.formdata) {
    var xhr = new XMLHttpRequest();
    xhr.open('POST', posturl);
    ...
  }
  ...

或者您可以发布到同一个文件,但使用一个标志来确定服务器上文件的来源。

Ps:你可能知道,但是,这个 Codesnipplets 和博客中的一个,需要清理以供生产使用。

一切顺利

于 2013-04-07T10:34:09.563 回答