上传照片方法

 

// chooseImage.js

复制代码
function updateElementStyle (element, styles) {
  for (const attrName in styles) {
    element.style[attrName] = styles[attrName]
  }
}
const ALL = '*'
function isWXEnv () {
  const ua = window.navigator.userAgent.toLowerCase()
  if (ua.match(/MicroMessenger/i) && ua.match(/MicroMessenger/i)[0] === 'micromessenger') {
    return true
  } else {
    return false
  }
}

function createInput({ count, sourceType, type, extension }) {
  const inputEl = document.createElement('input')
  inputEl.type = 'file'

  updateElementStyle(inputEl, {
    position: 'absolute',
    visibility: 'hidden',
    'z-index': -999,
    width: 0,
    height: 0,
    top: 0,
    left: 0
  })

  inputEl.accept = extension.map(item => {
    if (type !== ALL) {
      // 剔除.拼接在type后
      return `${type}/${item.replace('.', '')}`
    } else {
      // 在微信环境里,'.jpeg,.png' 会提示没有应用可执行此操作
      if (isWXEnv()) {
        return '.'
      }
      // 在后缀前方加上.
      return item.indexOf('.') === 0 ? item : `.${item}`
    }
  }).join(',')

  if (count > 1) {
    inputEl.multiple = 'multiple'
  }

  // 经过测试,仅能限制只通过相机拍摄,不能限制只允许从相册选择。
  if (sourceType.length === 1 && sourceType[0] === 'camera') {
    inputEl.capture = 'camera'
  }

  return inputEl
}

function hasOwn (obj, key) {
    const hasOwnProperty = Object.prototype.hasOwnProperty
    return hasOwnProperty.call(obj, key)
  }
  const files = {}
  /**
   * 从url读取File
   * @param {string} url
   * @param {Promise}
   */
function urlToFile (url) {
    var file = files[url]
    if (file) {
      return Promise.resolve(file)
    }
    if (/^data:[a-z-]+\/[a-z-]+;base64,/.test(url)) {
      return Promise.resolve(base64ToFile(url))
    }
    return new Promise((resolve, reject) => {
      var xhr = new XMLHttpRequest()
      xhr.open('GET', url, true)
      xhr.responseType = 'blob'
      xhr.onload = function () {
        resolve(this.response)
      }
      xhr.onerror = reject
      xhr.send()
    })
  }
  /**
   * base64转File
   * @param {string} base64
   * @return {File}
   */
function base64ToFile (base64) {
    base64 = base64.split(',')
    var type = base64[0].match(/:(.*?);/)[1]
    var str = atob(base64[1])
    var n = str.length
    var array = new Uint8Array(n)
    while (n--) {
      array[n] = str.charCodeAt(n)
    }
    return blobToFile(array, type)
  }
  /**
   * 简易获取扩展名
   * @param {string} type
   * @return {string}
   */
  function getExtname (type) {
    const extname = type.split('/')[1]
    return extname ? `.${extname}` : ''
  }
  /**
   * 简易获取文件名
   * @param {*} url
   */
function getFileName (url) {
    url = url.split('#')[0].split('?')[0]
    const array = url.split('/')
    return array[array.length - 1]
  }
  
  /**
   * blob转File
   * @param {Blob} blob
   * @param {string} type
   * @return {File}
   */
function blobToFile (blob, type) {
    if (!(blob instanceof File)) {
      type = type || blob.type || ''
      const filename = `${Date.now()}${getExtname(type)}`
      try {
        blob = new File([blob], filename, { type })
      } catch (error) {
        blob = blob instanceof Blob ? blob : new Blob([blob], { type })
        blob.name = blob.name || filename
      }
    }
    return blob
  }
  /**
   * 从本地file或者blob对象创建url
   * @param {Blob|File} file
   * @return {string}
   */
function fileToUrl (file) {
    for (const key in files) {
      if (hasOwn(files, key)) {
        const oldFile = files[key]
        if (oldFile === file) {
          return key
        }
      }
    }
    var url = (window.URL || window.webkitURL).createObjectURL(file)
    files[url] = file
    return url
}
  
function getSameOriginUrl (url) {
    const a = document.createElement('a')
    a.href = url
    if (a.origin === location.origin) {
      return Promise.resolve(url)
    }
    return urlToFile(url).then(fileToUrl)
}
  
function revokeObjectURL (url) {
    (window.URL || window.webkitURL).revokeObjectURL(url)
    delete files[url]
}
 
let imageInput = null
  
function chooseImage ({
    count=1,
    sizeType=['original'],
    sourceType=['camera','album'],
    extension=['jpg','png','jpeg'],
    success
  }) {
    // TODO handle sizeType 尝试通过 canvas 压缩
  
    if (imageInput) {
      document.body.removeChild(imageInput)
      imageInput = null
    }
  
    imageInput = createInput({
      count,
      sourceType,
      extension,
      type: 'image'
    })
    document.body.appendChild(imageInput)
  
    imageInput.addEventListener('change', function (event) {
      const tempFiles = []
      const fileCount = event.target.files.length
      for (let i = 0; i < fileCount; i++) {
        const file = event.target.files[i]
        let filePath
        Object.defineProperty(file, 'path', {
          get () {
            filePath = filePath || fileToUrl(file)
            return filePath
          }
        })
        if (i < count) tempFiles.push(file)
      }
      const res = {
        errMsg: 'chooseImage:ok',
        get tempFilePaths () {
          return tempFiles.map(({ path }) => path)
        },
        tempFiles: tempFiles
      }
      success(res)
      // TODO 用户取消选择时,触发 fail,目前尚未找到合适的方法。
    })
  
    imageInput.click()
  }
  
复制代码

调用这个方法:

复制代码
chooseImage({
            success: function (res) {
              let sizeLimit = 5 * 1024 * 1024
              let size = res.tempFiles[0].size
              if (size > sizeLimit) {
                layer.msg(`图片不能大于5M`, { icon: 5, shift: 6 });
                return
              }
              uploadPics[key] = res
              let imgEle = $(that).find('.image-item')
              let iconDelete = $(that).find('.image-item-delete')
              imgEle[0].src = res.tempFilePaths
              imgEle.show()
              iconDelete.show()
              iconDelete.on('click', function (e) {
                e.stopPropagation()
                imgEle.hide()
                iconDelete.hide()
                uploadPics[key] = ''
              })
            }
          })
复制代码

 

posted @   playforkeeps  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
点击右上角即可分享
微信分享提示