【问题标题】:Updating this Div from ajax response从 ajax 响应更新此 Div
【发布时间】:2017-09-26 07:15:04
【问题描述】:

我有以下form,它基本上接受文件上传,然后显示上传status。最后的status 转到status id。但是,我有多个表单,例如,当您更新第二个表单时,status 会显示在第一个 form 而不是第二个。

我怎样才能让它们分别更新,这取决于更新的那个。

这是我的代码:

<script>
function _(el) {
  return document.getElementById(el);
}

function uploadFile(element) {
  var file = _("file1").files[0];
  alert(file.name+" | "+file.size+" | "+file.type);
  var formdata = new FormData();
  formdata.append("file1", file);
  var ajax = new XMLHttpRequest();
  var uploadValue = element.getAttribute("data-uploadValue");
  ajax.upload.addEventListener("progress", progressHandler, false);
  ajax.addEventListener("load", completeHandler, false);
  ajax.addEventListener("error", errorHandler, false);
  ajax.addEventListener("abort", abortHandler, false);
  ajax.open("POST", "/upload/" + uploadValue); //
  ajax.send(formdata);
}

function progressHandler(event) {
  _("loaded_n_total").innerHTML = "Uploaded " + event.loaded + " bytes of " + event.total;
  var percent = (event.loaded / event.total) * 100;
  _("progressBar").value = Math.round(percent);
  _("status").innerHTML = Math.round(percent) + "% uploaded... please wait";
}

function completeHandler(event) {
  _("status").innerHTML = event.target.responseText;
  _("progressBar").value = 0; //wil clear progress bar after successful upload
}

function errorHandler(event) {
  _("status").innerHTML = "Upload Failed";
}

function abortHandler(event) {
  _("status").innerHTML = "Upload Aborted";
}
</script>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>

更新 1: 将 JS 更改为更依赖的东西。

更新 2: 决定将 JS 放在与表单相同的输出循环中(因此有多个脚本,每个表单一个)并在每个 id 中插入一个唯一编号 - 基本上使 id 唯一。虽然做法不好,但这仍然没有解决我的问题。

更新 3 在每个包含文本区域的上传表单之前,我都有另一个表单 - 这似乎会导致问题。 Alex Kudryashev 的答案在没有这些额外表格的情况下有效,但没有。

【问题讨论】:

  • 所有表单都使用相同的 ID 吗? ID 应该是唯一的。您应该使用类,然后使用相对于$(this) 的 DOM 导航方法。
  • 是的。这是由 Ajax 提交的表单,目前正在按预期工作,所以我宁愿不更改它,因为我缺乏 js 技能
  • 你必须改变它。 ID 必须是唯一的。 $("#status") 将始终选择页面上的第一个。
  • 使用 ID #id_selector 而不是 .class 选择器单独更新它们。由于类选择器可以应用于许多 div,但 ID 是唯一的。
  • “并且目前正在按预期工作” - 我怀疑当您在页面上实际使用多个这些时仍然会出现这种情况。相信我们,这是您首先要解决的问题,否则您可能会遇到各种问题。 ID 必须在 HTML 文档中是唯一的。

标签: javascript jquery html css ajax


【解决方案1】:

OP 中的问题在于getElementById,它只返回第一个元素。可行的解决方案是在每个表单(如果有多个)在绑定到表单的闭包内 中查找元素。像这样:
更新

我在每个上传表单之前都有另一个表单,其中包含一个文本区域 - 这似乎引起了问题。 Alex Kudryashev 的回答在没有这些额外表格的情况下有效,但没有。

查看代码中的更新。

<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <script>
        document.addEventListener("DOMContentLoaded", function () {
            for (var i = 0, form; form = document.forms[i]; ++i) {//iterate throu forms
                initForm(form);
            }
        });
        function initForm(frm) {
            //find elements of interest inside the form
            var fileUpload = frm.file1;//get by 'name' attribute inside the form
            var statusInfo = frm.querySelector('.status');
            var progressBar = frm.querySelector('.progress');
            var progressInfo = frm.querySelector('.loaded_n_total');

            //update. 'textarea' is in a separate form which doesn't contain 'file1'
            if (fileUpload)
               fileUpload.addEventListener('change', uploadFile);

            function uploadFile(e) {//'e' is 'change' event. It isn't used and may be ommited
                var file = this.files[0];// 'this' is fileUpload element
                //alert(file.name + " | " + file.size + " | " + file.type);
                console.log(file);
                var formdata = new FormData();
                formdata.append("file1", file, file.name);

                //update. A form with fileUpload contains other elements
                for (var i = 0, el; el = this.form.elements[i]; ++i) {
                    if (el !== this)
                        formdata.append(el.name, el.value);
                }

                statusInfo.innerHTML = 'prepare upload';
                var ajax = new XMLHttpRequest();
                var uploadValue = this.getAttribute("data-uploadValue");
                ajax.upload.addEventListener("progress", progressHandler, false);
                ajax.addEventListener("load", completeHandler, false);
                ajax.addEventListener("error", errorHandler, false);
                ajax.addEventListener("abort", abortHandler, false);
                ajax.open("POST", "/upload/" + uploadValue); //
                ajax.send(formdata);
            }
            function progressHandler(event) {
                progressInfo.innerHTML = "Uploaded " + event.loaded + " bytes of " + event.total;
                var percent = (event.loaded / event.total) * 100;
                progressBar.value = Math.round(percent);
                statusInfo.innerHTML = Math.round(percent) + "% uploaded... please wait";
            }

            function completeHandler(event) {
                statusInfo.innerHTML = event.target.responseText;
                progressBar.value = 0; //wil clear progress bar after successful upload
            }

            function errorHandler(event) {
                statusInfo.innerHTML = "Upload Failed";
            }

            function abortHandler(event) {
                statusInfo.innerHTML = "Upload Aborted";
            }
        }//initForm

    </script>
</head>
<body>
    <form enctype="multipart/form-data" method="post">
        <div class="file has-name is-fullwidth is-info">
            <label class="file-label">
                <input class="file-input" type="file" name="file1" data-uploadValue="form/1"><br>
                <span class="file-cta">
                    <span class="file-icon">
                        <i class="fa fa-upload"></i>
                    </span>
                    <span class="file-label">
                        Choose a file…
                    </span>
                </span>
                <div class="file-name">
                    <div style="color:red;" class="status"></div>
                    Supported file types: .png, .jpg, .jpeg and .gif
                </div>
            </label>
            <div style="display:none">
                <p class="loaded_n_total"></p>
                <progress class="progress" value="0" max="100" style="width:300px;"></progress>
            </div>
        </div>
    </form>
    <form enctype="multipart/form-data" method="post">
        <div class="file has-name is-fullwidth is-info">
            <label class="file-label">
                <input class="file-input" type="file" name="file1" data-uploadValue="form/2"
                       ><br>
                <span class="file-cta">
                    <span class="file-icon">
                        <i class="fa fa-upload"></i>
                    </span>
                    <span class="file-label">
                        Choose a file…
                    </span>
                </span>
                <div class="file-name">
                    <div style="color:red;" class="status"></div>
                    Supported file types: .png, .jpg, .jpeg and .gif
                </div>
            </label>
            <div style="display:none">
                <p class="loaded_n_total"></p>
                <progress class="progress" value="0" max="100" style="width:300px;"></progress>
            </div>
        </div>
    </form>
</body>
</html>

【讨论】:

  • 我在这些表单之前都有一个 textarea 表单,这似乎会导致问题......我已经更新了我的问题
  • 完美运行 - 感谢您的帮助!作为一名 Python 爱好者,我有很多东西要学,尤其是在 JS 方面 - 获得 50 次代表
【解决方案2】:

您不应在一个页面上多次定义相同的id。因为当您这样做并使用 id 定义 jquery 代码时,DOM 将考虑非常第一个 id 它会发现从文档顶部获取。因此,特定id 的第一次出现总是会被引用。

因此您需要将status 更改为类,因此:class="status" 然后在ajax 函数中参考您提交的表单引用该类,因此它只会将您的状态附加到相关元素。检查下面的代码:

$('#uploadform').ajaxForm({
    beforeSend: function() {
        $(this).find('.status').empty();
        var percentVal = '0%';
        bar.width(percentVal)
        percent.html(percentVal);
    },
    uploadProgress: function(event, position, total, percentComplete) {
        var percentVal = percentComplete + '%';
        bar.width(percentVal)
        percent.html(percentVal);
        //console.log(percentVal, position, total);
    },
    success: function() {
        var percentVal = '100%';
        bar.width(percentVal)
        percent.html(percentVal);
    },
    complete: function(xhr) {
        $(this).find('.status').html(xhr.responseText);
    }
});

【讨论】:

  • $(this) 不会传递给回调函数。
  • @Barmar,是的,实际上他必须将它放在将调用 ajax 的点击事件中。
  • 这与我的评论有什么关系。见stackoverflow.com/questions/20279484/…
【解决方案3】:

让我们来看看这部分:

    uploadProgress: function(event, position, total, percentComplete) {
        var percentVal = percentComplete + '%';
        bar.width(percentVal)
        percent.html(percentVal);
        //console.log(percentVal, position, total);
    },

因为您的代码引用栏和百分比如下:

var bar = $('.bar');
var percent = $('.percent');
var status = $('#status');

我希望发生的事情不仅是状态只会更新第一个,而且表格 1、2 直到 n 中的条形和百分比在更新时将始终显示相同的值,发生的任何更改都会反映到所有其他的也是如此。这是由于每个变量绑定的 DOM。因此,我将对您的代码进行一些更改,并以正确的方式进行:

<script>
    (function() {

        var forms = $(".some-upload-forms");

        for (var i = 0; i < forms.length; i++){
            initializeFormEvents(forms[i]);
        }

        function initializeFormEvents(form){
            var bar = form.find('.bar');
            var percent = form.find('.percent');
            var status = form.find('#status');
            var uploadForm = form.find("#uploadform");

            uploadForm.ajaxForm({
                beforeSend: function() {
                    status.empty();
                    var percentVal = '0%';
                    bar.width(percentVal)
                    percent.html(percentVal);
                },
                uploadProgress: function(event, position, total, percentComplete) {
                    var percentVal = percentComplete + '%';
                    bar.width(percentVal)
                    percent.html(percentVal);
                    //console.log(percentVal, position, total);
                },
                success: function() {
                    var percentVal = '100%';
                    bar.width(percentVal)
                    percent.html(percentVal);
                },
                complete: function(xhr) {
                    status.html(xhr.responseText);
                }
            })
        }
    })();


    </script>

还有你的html:

<div class='some-upload-forms">
    <form id="uploadform" enctype="multipart/form-data" method="post">
        <div class="file has-name is-fullwidth is-info">
          <label class="file-label">
            <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
            <span class="file-cta">
              <span class="file-icon">
                <i class="fa fa-upload"></i>
              </span>
              <span class="file-label">
                Choose a file…
              </span>
            </span>
            <span class="file-name">
              <div style="color:red;" id="status"></div>
              Supported file types: .png, .jpg, .jpeg and .gif
            </span>
          </label>
          <div style="display:none"><p id="loaded_n_total"></p>
          <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
        </div>
    </form>
</div>

然后你可以在一个页面中复制越来越多的表单,确保从开始复制;

【讨论】:

  • 你的意思是脚本也应该被复制吗?
  • 我稍微编辑一下代码,然后再试一次,顺便说一下,当你复制表单时,你需要从
    复制,所以你会有类似:
    ....
    ....
    ....
  • 是的,我已经做到了 - 仍在更新第一个,只是
  • 仔细检查了所有内容,它仍在更新第一个
【解决方案4】:

为了让您的上传者进入有效的可重复表单,您需要做的是检查每个表单并将 ID 替换为有意义的唯一 ID,并允许每个实例单独运行。

我将代码分为两个步骤。第一步是将无效的 HTML 转换为有效的 HTML:

function runner(index) {
  var form = document.getElementById('upload_form');
  if (!form) return false;
  form.id = 'upload_form-' + index;
  var children = document.querySelectorAll('#upload_form-' + index + ' *');
  for (i = 0; i < children.length; i++) {
    if (children[i].id) {
      children[i].id = children[i].id + '-' + index;
    }
  }
  return true;
}

var index = 0;

while (runner(index)) {
  index++;
}

这会遍历您页面中 ID 为 upload_form 的所有表单,并在他们的 ids 和他们孩子的 ids 之后附加一个漂亮的小 index,确保它们变得独一无二。

这是一个小测试:

function runner(index) {
  var form = document.getElementById('upload_form');
  if (!form) return false;
  form.id = 'upload_form-' + index;
  var children = document.querySelectorAll('#upload_form-' + index + ' *');
  for (i = 0; i < children.length; i++) {
    if (children[i].id) {
      children[i].id = children[i].id + '-' + index;
    }
  }
  return true;
}

var index = 0;

while (runner(index)) {
  index++;
}
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>
<form id="upload_form" enctype="multipart/form-data" method="post">
  <div class="file has-name is-fullwidth is-info">
    <label class="file-label">
        <input class="file-input" type="file" name="file1" id="file1" data-uploadValue="{{ item[0] }}"  onchange="uploadFile(this)"><br>
        <span class="file-cta">
          <span class="file-icon">
            <i class="fa fa-upload"></i>
          </span>
          <span class="file-label">
            Choose a file…
          </span>
        </span>
        <span class="file-name">
          <div style="color:red;" id="status"></div>
          Supported file types: .png, .jpg, .jpeg and .gif
        </span>
      </label>
    <div style="display:none">
      <p id="loaded_n_total"></p>
      <progress id="progressBar" class="progress" value="0" max="100" style="width:300px;"></progress></div>
  </div>
</form>

运行它并检查表单,您会注意到它们获得了索引,他们的孩子也拥有id 属性。


第二步是确保您当前的代码查找、获取和使用父表单的id,以便正确选择其中元素的ids。为此,我首先获取正在使用的输入的父表单索引,然后使用闭包将此 index 传递给每个后续函数调用,因此 _() 始终选择正确的元素。

function _(el, index) {
  return document.getElementById(el + '-' + index);
}

function uploadFile(element) {
  var formId = element.closest('form').id,
    index = formId.split('-')[formId.split('-').length - 1],
    file = _("file1", index).files[0];
  alert(file.name + " | " + file.size + " | " + file.type);
  var formdata = new FormData();
  formdata.append("file1", file);
  var ajax = new XMLHttpRequest();
  var uploadValue = element.getAttribute("data-uploadValue");
  ajax.upload.addEventListener("progress", 
    (function(n) { progressHandler(event, n) })(index), 
    false);
  ajax.addEventListener("load", 
    (function(n) { completeHandler(event, n) })(index), 
    false);
  ajax.addEventListener("error", 
    (function(n) { errorHandler(event, n) })(index), 
    false);
  ajax.addEventListener("abort", 
    (function(n) { abortHandler(event, n) })(index), 
    false);
  ajax.open("POST", "/upload/" + uploadValue); //
  ajax.send(formdata);
}

function progressHandler(event, index) {
  _("loaded_n_total", index).innerHTML = "Uploaded " + event.loaded + " bytes of " + event.total;
  var percent = event.total ? event.loaded * 100 / event.total : 0;
  _("progressBar", index).value = Math.round(percent);
  _("status", index).innerHTML = Math.round(percent) + "% uploaded... please wait";
}

function completeHandler(event, index) {
  _("status", index).innerHTML = event.target.responseText;
  _("progressBar", index).value = 0; //wil clear progress bar after successful upload
}

function errorHandler(event, index) {
  _("status", index).innerHTML = "Upload Failed";
}

function abortHandler(event, index) {
  _("status", index).innerHTML = "Upload Aborted";
}

旁注:我冒昧改变了

var percent = (event.loaded / event.total) * 100;

...进入:

var percent = event.total ? event.loaded * 100 / event.total : 0;

...,因为(可能是由于 SO 上不允许 POST),event.total0 使 percent NaN,在下一行生成错误。如果您在实际示例中没有遇到此问题,请确保将此行改回适合您的行。

据我测试,它似乎可以工作,唯一的错误是 SO 不允许 POST 请求,一旦文件被选择并附加到表单。

如果您遇到任何麻烦,请告诉我,我会尽力弄清楚发生了什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-06
    • 2012-02-17
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 1970-01-01
    相关资源
    最近更新 更多