首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多个Dropzone.js按钮

问多个Dropzone.js按钮
EN

Stack Overflow用户
提问于 2015-05-28 09:16:47
回答 1查看 3.2K关注 0票数 1

我可以有无限多的上传按钮(每一行一个),这些按钮是使用dropzone.js上传文件的触发器。

如果我以jQuery的方式初始化下拉区域,我可以在每个按钮上上传一个文件,但是我不知道如何访问每个事件回调?

代码语言:javascript
复制
var dropzone = $('.btn-upload').dropzone({
        url: '/api/?action=upload',
        uploadMultiple: false,
        createImageThumbnails: false,
        acceptedFiles: 'image/*',
        autoProcessQueue: true,
        previewTemplate: '<div class="dz-preview dz-file-preview"/>'
    });

dropzone.on('success', function(file, xhr, formData) {
    console.log('done');
});

dropzone.on('error', function(file, errorMessage, xhr) {
    console.log('error');
});

如果我这样做,事件回调就能工作,但我只能从第一个按钮上传:

代码语言:javascript
复制
var dropzone = new Dropzone ('.btn-upload', {
        url: '/api/?action=upload',
        uploadMultiple: false,
        createImageThumbnails: false,
        acceptedFiles: 'image/*',
        autoProcessQueue: true,
        previewTemplate: '<div class="dz-preview dz-file-preview"/>'
    });

dropzone.on('success', function(file, xhr, formData) {
    console.log('done');
});

dropzone.on('error', function(file, errorMessage, xhr) {
    console.log('error');
});

如何添加无限数量的实例并访问事件回调?

EN

回答 1

Stack Overflow用户

发布于 2015-12-01 19:49:44

作为参考,下面是我用来测试的HTML和CSS (为方便起见,JavaScript和CSS都包含在HTML中):

代码语言:javascript
复制
<html>
  <head>
    <link type="text/css" rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
    <style>
      .dropzone {
        border: 2px dashed #428BCA;
        border-radius: 5px 5px 5px 5px;
        padding: 5px;
      }

      .dropzone.dz-clickable { cursor: pointer; }
      .dropzone.dz-clickable * { cursor: default; }
      .dropzone.dz-clickable .dz-message, .dropzone.dz-clickable .dz-message * { cursor: pointer; }
      .dropzone.dz-started .dz-message { display: none; }
      .dropzone.dz-drag-hover { border-style: solid; }
      .dropzone.dz-drag-hover .dz-message { opacity: 0.5; }

      .dropzone .dz-message {
        color: #666;
        font-size: 1.2em;
        margin: 0.2em 0;
        text-align: center;
      }

      .dropzone-previews { display: none !important; }
    </style>
  </head>
  <body>
    <table class="table">
      <thead>
        <tr>
          <th>Item</th>
          <th>Result</th>
          <th>Drop Zone</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Item 1</td>
          <td class="js-result"></td>
          <td>
            <form action="/api/?action=upload" method="post" class="dropzone dz-clickable" id="item-1-dropzone" enctype="multipart/form-data">
              <input type="hidden" name="id" value="1" />
              <div class="dz-message">Drop here</div>
            </form>
          </td>
        </tr>
        <tr>
          <td>Item 2</td>
          <td class="js-result"></td>
          <td>
            <form action="/api/?action=upload" method="post" class="dropzone dz-clickable" id="item-2-dropzone" enctype="multipart/form-data">
              <input type="hidden" name="id" value="2" />
              <div class="dz-message">Drop here</div>
            </form>
          </td>
        </tr>
        <tr>
          <td>Item 3</td>
          <td class="js-result"></td>
          <td>
            <form action="/api/?action=upload" method="post" class="dropzone dz-clickable" id="item-3-dropzone" enctype="multipart/form-data">
              <input type="hidden" name="id" value="3" />
              <div class="dz-message">Drop here</div>
            </form>
          </td>
        </tr>
      </tbody>
    </table>
    <div class="dropzone-previews"></div>

    <script type="text/javascript"
            src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script type="text/javascript"
            src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/4.2.0/min/dropzone.min.js"></script>
    <script>
      // turn off DropZone's auto discovery feature
      Dropzone.autoDiscover = false;

      $(document).ready(function () {
        /* JavaScript discussed below goes here */
      });
    </script>
  </body>
</html>

需要注意的两件事是:

  1. 元素<div class="dropzone-previews"></div>似乎需要存在,但是我用CSS隐藏它,因为我不需要它。
  2. 我将关闭Dropzone的自动发现功能,因为我将定义和自定义各个拖放区域。

为了定义拖放区域,我找到了两种不同的方法。第一个问题并不理想,因为这个问题表明了“无限数量的上传按钮”的潜力,但它有助于回答如何访问单个页面上的多个拖放区域的回调问题。

第一个解决方案,使用ID定义每个拖放区域

代码语言:javascript
复制
$("form#item-1-dropzone").dropzone({
  url: $("form").attr("action"),
  previewsContainer: ".dropzone-previews",
  init: function () {
    this.on("success", function (file, response, event) {
      var $preview = $(file.previewElement).find("img");
      $("form#item-1-dropzone").closest("tr").find(".js-result").html($preview);
    });

    this.on("error", function (file, errorMessage, xhr) {
      console.error("Dropzone 1 Error");
    });
  }
});

$("form#item-2-dropzone").dropzone({
  url: $("form").attr("action"),
  previewsContainer: ".dropzone-previews",
  init: function () {
    this.on("success", function (file, response, event) {
      var $preview = $(file.previewElement).find("img");
      $("form#item-2-dropzone").closest("tr").find(".js-result").html($preview);
    });

    this.on("error", function (file, errorMessage, xhr) {
      console.error("Dropzone 2 Error");
    });
  }
});

$("form#item-3-dropzone").dropzone({
  url: $("form").attr("action"),
  previewsContainer: ".dropzone-previews",
  init: function () {
    this.on("success", function (file, response, event) {
      var $preview = $(file.previewElement).find("img");
      $("form#item-3-dropzone").closest("tr").find(".js-result").html($preview);
    });

    this.on("error", function (file, errorMessage, xhr) {
      console.error("Dropzone 3 Error");
    });
  }
});

每个拖放区域都是基于表单的唯一ID属性定义的,该属性允许我控制在成功上传时更新哪个表格单元格。

备注:用于测试我使用过的图像的,因为Dropzone生成了图像的预览,所以我只需抓取它并将其放入表中,以证明一切正常运行。

使用每个init定义中的如这里所讨论的属性,可以为每个拖放区域指定唯一的success和error事件处理程序。

这种方法的缺点是,为了处理每个拖放区域,有大量重复的代码;它不能很好地扩展。

第二个解,一个可缩放的解

从最初的问题中,我假设表中的每个拖放区域都希望在成功时对包含它的行进行操作,因此我们需要知道哪一行是成功事件处理程序的一部分。这被证明是困难的,因为这些信息没有在JavaScript中公开。每个表单中的<input type="hidden">元素用于使用id值唯一地标识每个表单(注意,这里不再需要第一个解决方案中使用的form元素上的id属性)。隐藏的输入将自动作为上传的一部分提交,因为它包含在<form></form>元素中,我特意编写了服务器端代码,以便在成功时返回ID值。因此,我现在可以从第一个解决方案中获得相同的结果,只需少得多的代码。

代码语言:javascript
复制
$("form.dropzone").dropzone({
  url: $("form").attr("action"),
  previewsContainer: ".dropzone-previews",
  init: function () {
    this.on("success", function (file, response, event) {
      var $preview = $(file.previewElement).find("img");
      var $input = $("table input[value='" + response.id + "']");
      if ($input.length) {
        var $result = $input.closest("tr").find(".js-result");
        $result.html($preview);
      }
    });

    this.on("error", function (file, errorMessage, xhr) {
      console.error("Dropzone Error");
    });
  }
});

response变量包含从服务器端脚本返回的任何内容。在我的例子中,它是一个类似于{ "id": 2 }的JSON字典,我可以使用response.id访问这个值。

当然,您可以将附加的值传递给服务器,然后返回到允许其他逻辑来确定如何处理成功或失败的上载。您还可以对每个表单使用完全不同的URL,这也会影响传递给成功事件处理程序的结果。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30502231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档