上传功能实现

一、利用Form表单

特点:兼容性最好,但实现起来有点麻烦。

iframe的作用是禁止表单提交默认的网页刷新,起到局部刷新的作用。

上传
$(".submit").on("click", function() {
  const multipartFrame = $('iframe[name="multipartFrame"]');
  if (multipartFrame.length) {
    let tIframe = multipartFrame[0].contentWindow;
    tIframe.message = '';
    tIframe.statusCode = '';
  }

  // 这里是对上传的内容做判断处理,如果 return false,就不会触发 submit 默认的提交事件
  if (!$(".file-input").val()) {
    console.log("无内容");
    return false;
  }
});

// iframe元素首次加载和接收到响应时会触发,响应结果会显示在iframe里,如果请求失败了的话,iframe里的内容就为空
$('iframe[name="multipartFrame"]').on("load", function() {
  let iframeDom = this.contentDocument
    ? this.contentDocument
    : window.frames[this.name].document;

  if (iframeDom.readyState === "complete") {
    let responseText = iframeDom.body.textContent;
    if (!responseText) {
      return false;
    }
    // 响应结果
    let json = JSON.parse(responseText) || {};
    // 然后对响应结果做业务处理
  }
});

二、使用 FormData

就是平时用的 post 请求,Content-Type默认就是: multipart/form-data; 。

示例:


上传
// 预览
$("#file-input").on("change", function() {
  let fileReader = new FileReader(),
    fileType = this.files[0].type;
  fileReader.onload = function() {
    if (/^image/.test(fileType)) {
      $(``).appendTo("body");
    }
  };
  fileReader.readAsDataURL(this.files[0]);
});

// 上传
$(".J-upload").on("click", function() {
  let formData = new FormData(),
    input = $("#file-input")[0];
  if(!input.files.length){
    return alert('请选择文件');
  }
  formData.append("img", input.files[0]);
  fetch("/uploadImg", {
    method: "POST",
    body: formData
  }).then();
});

三、多文件上传

多文件上传就是在 file 标签添加 multiple 属性。

//设置 multiple属性

上传
$(".J-upload").on("click", function() {
  let formData = new FormData(),
    input = $("#file-input")[0];
  if(!input.files.length){
    return alert('请选择文件');
  }
  //多文件上传需要遍历添加到 fromdata 对象
  for(var i = 0; i < input.files.length; i++){
    formData.append('img', input.files[i]);
  }
  fetch("/uploadImg", {
    method: "POST",
    body: formData
  }).then();
});

四、上传进度条

使用iframe没法获取上传进度,但XHR2的 xhr.upload.onprogress 可以实现上传进度条。

注意:xhr.upload.onprogress要写在xhr.send方法前面,否则event.lengthComputable状态不会改变,只有在最后一次才能获得,也就是100%的时候

选择文件(可多选):
function submitUpload() {
    var progressSpan = document.querySelector('#progress > span');
    var fileList = document.getElementById('f1').files;
    progressSpan.style.width='0';
    progressSpan.classList.remove('green');

    if(!fileList.length){
      return alert('请选择文件');
    }

    var fd = new FormData();
    for(var i =0; i 90){ //进度条变色
                progressSpan.classList.add('green');
            }
        }
    }
    xhr.send(fd);
}
//绑定提交事件
document.getElementById('btn-submit').addEventListener('click',submitUpload);

五、拖拽上传

drop your image here
$(".img-container").on("dragover", function (event) {
  // 拖拽图片的时候dragover和drop事件里的默认效果一定要禁掉,不然会变成网页里打开图片的效果
  event.preventDefault();
}).on("drop", function(event) {
  event.preventDefault();
  let file = event.originalEvent.dataTransfer.files[0];
  console.log({file})
  // 然后就跟处理input获取到的file一样了
});

六、在编辑框里粘贴上传

粘贴的方式,通常是在一个编辑框里操作,如把div的contenteditable设置为true: 

 
hello, paste your image here
$("#editor").on("paste", function(event) {
    let file = event.originalEvent.clipboardData.files[0];
});

但是Safari的粘贴不是通过event传递的,它是直接在输入框里面添加一张图片,它新建了一个img标签,并把img的src指向一个blob的本地数据。

上传功能实现_第1张图片

$("#editor").on("paste", function(event) {
    // 需要setTimeout 0等图片出来了再处理
    setTimeout(() => {
        let img = $(this).find("img[src^='blob']")[0];
        console.log(img.src);
    }, 0);
});

七、大文件上传

切片上传,断点续传。

详情

八、参考文章

  • 人人网FED:前端本地文件操作与上传
  • 掘金:写给新手前端的各种文件上传攻略,从小图片到大文件断点续传

 

 

 

 

 

你可能感兴趣的:(JavaScript)