A simple HTML5 file upload jQuery plugin
Feb 28, 2017 · 2 分钟阅读

;(function($) {
  $.fn.html5upload = function(options) {
    var cfgs = $.extend({
      url: '',
      tmpl: '',
      uploadBtn: '',
      previewContainer: '',
      multiple: false,
      onProgress: null,
      onSuccess: null,
      onError: null
    }, options);

    var $el = $(this);
    var $uploadBtn = $(cfgs.uploadBtn);
    var $progressBar = $(cfgs.progressBar);
    var $previewContainer = $(cfgs.previewContainer);
    var datas = [];
    var xhrs = [];
    var uploadIndex = 0;
    var tmpl = cfgs.tmpl || '<li class="weui-uploader__file" data-upload-index="#index#" style="background-image:url(#url#)"><span class="ui-progress"></span><span class="ui-cancel"></span></li>';

    $el.on('change', function(e) {
      var url = window.URL || window.webkitURL || window.mozURL;
      var files = e.target.files;

      $.each(files, function(i, file) {
        var src;
        var newTmpl = tmpl;

        uploadIndex++;
        file.uploadIndex = uploadIndex;
        datas.push(file);

        if (url) {
          src = url.createObjectURL(file);
        } else {
          src = e.target.result;
        }

        if (!cfgs.multiple) {
          $previewContainer.css('background-image', 'url(' + src + ')');
        } else {
          newTmpl = newTmpl.replace('#url#', src).replace('#index#', file.uploadIndex);
          $previewContainer.append($(newTmpl));
        }
      });
    });

    $uploadBtn.on('click', function() {
      var countSuccess = 0;
      var countError = 0;
      var total = datas.length;

      if (datas.length > 0) {
        $uploadBtn.prop('disabled', true).addClass('disabled');
      }

      $.each(datas, function(i, file) {
        var data = new FormData();
        var uploadIndex = file.uploadIndex;
        var $preview = $previewContainer.find('li[data-upload-index=' + uploadIndex + ']');

        data.append(file.name ? file.name : 'file-' + i, file);

        var currentXhr = $.ajax({
          url: cfgs.url,
          data: data,
          cache: false,
          contentType: false,
          processData: false,
          type: 'POST',
          success: function(data) {
            if (typeof cfgs.onSuccess === 'function') {
              cfgs.onSuccess(file, data);
            } else {
              console.log(file.name, data);
            }

            countSuccess++;
            datas = removeElement(datas, uploadIndex, 'uploadIndex');
          },
          error: function(jqXHR, textStatus, errorThrown) {
            if (typeof cfgs.onError === 'function') {
              cfgs.onError(file, textStatus);
            } else {
              console.log(file.name, textStatus);
            }

            countError++;
          },
          complete: function() {
            if (total === countSuccess + countError) {
              $uploadBtn.prop('disabled', false).removeClass('disabled');
              xhrs = [];
            }
          },
          xhr: function() {
            var xhr = $.ajaxSettings.xhr();

            if (xhr.upload) {
              xhr.upload.addEventListener('progress', function(e) {
                if (e.lengthComputable) {
                  if (typeof cfgs.onProgress === 'function') {
                    cfgs.onProgress(file, e.loaded, e.total);
                  } else {
                    $preview.find('.ui-progress').animate({
                      width: parseInt((e.loaded / e.total) * 100, 10) + '%'
                    });
                    console.log(file.name, e.loaded, e.total);
                  }
                }
              }, false);
            }

            return xhr;
          }
        });

        xhrs.push({
          xhr: currentXhr,
          index: uploadIndex
        });
      });
    });

    $previewContainer.on('click', 'li .ui-cancel', function() {
      var index = parseInt($(this).parent('li').remove().data('upload-index'), 10);
      datas = removeElement(datas, index, 'uploadIndex');

      $.each(xhrs, function(i, xhr) {
        if (xhr.index === index) {
          xhr.xhr.abort();
          return false;
        }
      });
    });

    return this;
  }

  function removeElement(arr, value, prop) {
    var rest = arr.slice();

    for (var i = 0; i < rest.length; i++) {
      if (prop && rest[i][prop] === value || !prop && rest[i] === value) {
        rest.splice(i, 1);
        break;
      }
    }

    return rest;
  }
})(jQuery);
← Previous Post Next Post →

Ryun的博客
与其感慨路难行,不如马上出发。

atom css design git html javascript jekyll laravel life mac mobile optimization sublime tool vscode vue
mac

About

你好,❤朋友

这里是 Ryun 的博客 📝

📝记录了我学习 🔎的过程

作为一名前端攻城狮 🦁

希望能和大家一起 🔎

共同进步 🏃

🦁的特长:

  • HTML5
  • CSS3
  • JavaScript
  • Vue.js
  • 微信小程序
  • 熟练配合 Node.js、PHP 和 Laravel
  • 熟练使用各种开发和设计工具

🦁喜欢 🆒🆒的东西

对提升效率和美感的事物有兴趣 😋

欢迎 👏交流


see this hugo-theme-dream-ink