美文网首页
记录一下目前项目常用到的一些工具方法

记录一下目前项目常用到的一些工具方法

作者: 人猿Jim | 来源:发表于2021-02-22 18:29 被阅读0次

    上传与下载

    首先要了解数据转换

    图片来源 (https://shanyue.tech/post/binary-in-frontend/#%E6%95%B0%E6%8D%AE%E8%BE%93%E5%85%A5)

    下载

    • 关于 application/octet-stream 和 Content-Disposition
      浏览器并不认得这是什么类型,也不知道应该如何展示,只知道这是一种二进制文件,因此遇到content-type为application/octet-stream的文件时,浏览器会直接把它下载下来。这个类型一般会配合另一个响应头Content-Disposition,该响应头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者网页的一部分),还是以附件的形式下载并保存到本地。
    /**
     * 使用a标签下载一个文件
     * @param {} url  下载文件的接口路径(可以提交要下载文件的名称来修改下载文件的路径) 或者 下载文件的路径(不能修改下载文件的名称)
     *  例如:http://xx/xxx/xxx/download?filename='123' 或者 http://xx/xxx/xxx/download/123.pdf
     */
    export const createIFrameDownLoad = (url) => {
      const iframeDom = document.createElement('iframe')
      iframeDom.style.zIndex = -100
      iframeDom.style.position = 'fixed'
      document.body.insertBefore(iframeDom, document.body.children[0])
      const iframeWin = iframeDom.contentWindow // 1.获取iframe中的window
      const iframeDocs = iframeWin.document // 2.获取iframe中的document
      iframeDocs.write(`<!doctype html>`)
      iframeDocs.write(`
        <html lang="en">
        <head>
        <meta charset="UTF-8">
        </head>
        <body>
        <a href="${url}"  target="_self" id="downLoad" ></a>
        </body>
        </html>
      `)
      const a = iframeDocs.querySelector('#downLoad')
      a.click()
      setTimeout(() => {
        document.body.removeChild(iframeDom)
      }, 10000)
    }
    /**
     *  
     * @param {} src 文件路径 'https://dakaname.oss-cn-hangzhou.aliyuncs.com/file/2018-12-28/1546003282521.pdf'
     * @param {} name
     */
    export const downFile = function(src, name = '') {
      // 下载非同源图片
      const x = new XMLHttpRequest()
      // 禁止浏览器缓存;否则会报跨域的错误
      x.open('GET', src, true) // 打开对象,也可以说是设置参数
      x.responseType = 'blob'
      x.onload = function(e) {
        // 异步请求加载完成后所执行的函数
        const url = window.URL.createObjectURL(x.response)
        const a = document.createElement('a')
        a.href = url
        a.download = name
        a.click()
      }
      x.send()
    }
    /**
     * 注意 axios 需要添加 :responseType = 'blob'
     * @param {*} content 文件流内容
     * @param {*} name 文件的名称
     */
    export const downLoadFileByStream = (content, name, type = '.xls') => {
      var elink = document.createElement('a')
      // name为后台返给前端的文件名,后缀名必须加,后台有返回后缀就不用管,不然下载在本地不好打开。
      elink.download = name + type
      elink.style.display = 'none'
      var blob = new Blob([content])
      elink.href = URL.createObjectURL(blob)
      document.body.appendChild(elink)
      elink.click()
      setTimeout(() => {
        document.body.removeChild(elink)
      }, 10000)
    }
    export const  downloadfile = (res) => {
       var blob = new Blob([res.data], { type: 'application/octet-stream;charset=UTF-8' })
       var contentDisposition = res.headers['content-disposition']
       var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
       var result = patt.exec(contentDisposition)
       var filename = result[1]
       var downloadElement = document.createElement('a')
       var href = window.URL.createObjectURL(blob) // 创建下载的链接
       var reg = /^["](.*)["]$/g
       downloadElement.style.display = 'none'
       downloadElement.href = href
       downloadElement.download = decodeURI(filename.replace(reg, '$1')) // 下载后文件名
       document.body.appendChild(downloadElement)
       downloadElement.click() // 点击下载
       document.body.removeChild(downloadElement) // 下载完成移除元素
       window.URL.revokeObjectURL(href)
    }
    

    上传

    上传经常要配和对话框进行文件上传进度展示
    目前接触到的上传基本为multipart/form-data(二进制文件上传)
    基本用的是FormData的API,而上传需要处理的更多的是文件的类型筛选和进度展示,中断,重传,拖拽等

    节流与防抖

    防抖:对于短时间内连续触发的事件(如滚动事件,按钮提交),防抖的含义就是让某个时间期限(如500毫秒)内,事件处理函数只执行一次(最后一次)
    ex:滚动事件用防抖打印console.log只会出现一次

    /**
    * 防抖函数 -> 会把前一个清除
    * @param method 事件触发的操作
    * @param delay 多少毫秒内连续触发事件,不会执行(默认500毫秒)
    * @returns {Function} handleInput:debounce(function(val){}){ console.log(val)  }
    */
    const debounce = (method, delay) => {
      delay = delay || 500
      let timer = null
      return function() {
        const self = this
        const args = arguments
        timer && clearTimeout(timer)
        timer = setTimeout(function() {
          method.apply(self, args)
        }, delay)
      }
    }
    

    节流:如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效(类似开关)。
    ex:滚动事件用节流打印console.log,每500ms会出现一次

    function throttle(fn,delay=500){
        let valid = true
        return function() {
          const self = this
          const args = arguments
           if(!valid){
               //休息时间 暂不接客
               return false 
           }
           // 工作时间,执行函数并且在间隔期内把状态位设为无效
            valid = false
            setTimeout(() => {
                fn.apply(self,args)
                valid = true;
            }, delay)
        }
    }
    

    相关文章

      网友评论

          本文标题:记录一下目前项目常用到的一些工具方法

          本文链接:https://www.haomeiwen.com/subject/mexxiktx.html