一些H5公用JS方法

206 阅读5分钟

1. 系统或浏览器判断相关

  // common.js
  //  判断ios和安卓系统
  isSystem(e) {
    let u = navigator.userAgent
    let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1 //  android终端
    if (isAndroid) {
      return 'android'
    }
    return 'ios'
  },
  
    // 判断微信浏览器类型
  checkPlatform() {
    if (/MicroMessenger/i.test(navigator.userAgent)) {
      // 这是微信平台下浏览器
      return 'Messenger'
    }
    if (/android/i.test(navigator.userAgent)) {
      // 这是Android平台下浏览器
      return 'Android'
    }
    if (/iphone os/i.test(navigator.userAgent)) {
      // 这是iOS平台下浏览器
      return 'iOS'
    }
    if (/Linux/i.test(navigator.userAgent)) {
      // 这是Linux平台下浏览器
      return 'Linux'
    }
    if (/Linux/i.test(navigator.platform)) {
      // 这是Linux操作系统平台
      return 'Linux'
    }
  },
  
    // 判断iphone底部黑线类型手机 iPhoneX,iPhone XS Max,iPhoneXR,iphone11
  isIphoneX() {
    // iPhone X、iPhone XS
    const isIPhoneX = /iphone/gi.test(window.navigator.userAgent) && window.devicePixelRatio && window.devicePixelRatio === 3 && window.screen.width === 375 && window.screen.height === 812
    // iPhone XS Max iphone11 Pro
    const isIPhoneXSMax = /iphone/gi.test(window.navigator.userAgent) && window.devicePixelRatio && window.devicePixelRatio === 3 && window.screen.width === 414 && window.screen.height === 896
    // iPhone XR iphone11
    const isIPhoneXR = /iphone/gi.test(window.navigator.userAgent) && window.devicePixelRatio && window.devicePixelRatio === 2 && window.screen.width === 414 && window.screen.height === 896
    if (isIPhoneX || isIPhoneXSMax || isIPhoneXR) return true
    return false
  },

2. 常用数据验证(正则及非正则)

    // common.js
    
    // 检验手机号码
  validPhone (num) {
    num = Number(num)
    let phoneReg = /^((\+?86)|(\(\+86\)))?(13[0123456789][0-9]{8}|15[0123456789][0-9]{8}|14[0123456789][0-9]{8}|17[0123456789][0-9]{8}|18[0123456789][0-9]{8}|16[0123456789][0-9]{8}|19[0123456789][0-9]{8})$/
    return phoneReg.test(num)
  },
  
  // 验证手机号码和固话
  validAllPhone(num) {
    let phoneReg = /^((\+?86)|(\(\+86\)))?(13[0123456789][0-9]{8}|15[0123456789][0-9]{8}|14[0123456789][0-9]{8}|17[0123456789][0-9]{8}|18[0123456789][0-9]{8}|16[0123456789][0-9]{8}|19[0123456789][0-9]{8})$/
    let isfixed = /^([0-9]{3,4})?[0-9]{7,8}$|^0\d{2,3}-\d{7,8}$/
    return phoneReg.test(num) || isfixed.test(num)
  },
  
   // 验证物流号
  validateLogisticsNo (logisticsNo) {
    if (!/[a-z-A-Z-0-9]{1,30}$/.test(logisticsNo)) {
      return false
    }
    return true
  },
  
   // 验证银行卡号
  formatBankNo(BankNo) {
    let numberBankNo = parseInt(BankNo.replace(/\s/g, ''))
    console.log(numberBankNo)
    if (/^[0-9]{16}$|^[0-9]{19}$/.test(numberBankNo)) {
      return true
    }
    return false
  },
  
   // 验证税号(15或者17或者18或者20位字母、数字组成)
  checkTax(obj) {
    if (obj !== '' && obj != null) {
      return true
    }
    return false
  },

   // 验证邮箱
  isEmail(str) {
    let reg = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/
    if (reg.test(str)) {
      return true
    }
    return false
  },

   // 验证身份证号码
  isIdentifyCardNo(str) {
    let reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
    if (reg.test(str)) {
      return true
    }
    return false
  },

   // 验证纯数字
  isNumber(str) {
    let reg = /^[0-9]*$/
    if (reg.test(str)) {
      return true
    }
    return false
  },

   // 验证是否有表情包输入
  checkEmoji(str) {
    let reg = /[^\u0020-\u007E\u00A0-\u00BE\u2E80-\uA4CF\uF900-\uFAFF\uFE30-\uFE4F\uFF00-\uFFEF\u0080-\u009F\u2000-\u201f\u2026\u2022\u20ac\r\n]/g
    if ((typeof str === 'string') && str.match(reg)) {
      return false
    }
    return true
  },
  
 /***
   * 判断数据类型
   * @param val 当前验证数据
   * @param type 想要验证的数据类型Object, Array ,Undefined, Null, Boolean, Number和String
  */
  isJsType(val, type) {
    return Object.prototype.toString.call(val) === `[object ${type}]`
  },
  
   // 判断对象是否为空
  isNull(data) {
    if (data == null || data == '' || typeof (data) === 'undefined') {
      return true
    }
    return false
  },

3. H5备用方法

    // h5页面跳转到外链还能返回到当前页面的方法
    jumpPage() {
      let url = 'https://github.com/xszi'
      let webPath = encodeURIComponent(location.href)
      window.location.href = url + '&returnUrl=' + webPath
    }
   // 深拷贝
  deepCopy(obj) {
    let result = Array.isArray(obj) ? [] : {}
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        if (typeof obj[key] === 'object' && obj[key] !== null) {
          result[key] = utils.deepCopy(obj[key]) // 递归复制
        } else {
          result[key] = obj[key]
        }
      }
    }
    return result
  },

4. axios拦截请求响应, 简化get,post请求方法

// request.js
'use strict'

import axios from 'axios'
import storage from './localStorage.js'
import store from '../store/store.js'
import router from '../router/index.js'
import {
  Toast
} from 'vant'
const baseURL = process.env.NODE_ENV === 'development' ? '/api' : '/mall/def'

export let mallAxios = axios.create({
  // 基础URL
  baseURL,
  // 响应超时时间
  timeout: 20000
})

// 请求拦截处理函数
let reqIntercept = (config) => {
  const token = localStorage.getItem('token')
  // 配置usBusId
  if (store.state.busId) {
    config.headers['ucBusId'] = store.state.busId
  }
  // 配置token
  if (token) {
    config.headers['ucToken'] = token
  }
  // 在发送请求之前做些什么
  // config.headers['ucBusId'] = '4856'
  // config.headers['ucToken'] = '119'
  return config
}
// 请求拦截错误时的处理函数
let reqErrorIntercept = (error) => {
  // 对请求错误做些什么
  return Promise.reject(error)
}

// 给mallAxios实例添加 请求拦截器
mallAxios.interceptors.request.use(reqIntercept, reqErrorIntercept)

// 响应拦截处理函数
let resIntercept = (response) => {
  // 请求状态码
  const status = response.status
  if (status === 200) {
    // if (response.data.status === 500) {
    //   Toast(response.data.message)
    //   return
    // }
    handleErrCode(response.data)
    return Promise.resolve(response.data)
  } else {
    return Promise.reject(response)
  }
}
// 响应拦截错误时的处理函数
let resErrorIntercept = (error) => {
  // 断网或者请求超时状态
  if (!error.response) {
    if (error.message.includes('timeout')) {
      Toast({
        message: '网络请求超时',
        duration: 1500
      })
      console.log('网络超时')
    } else {
      Toast({
        message: '网络开小差了',
        duration: 1500
      })
      console.log('网络异常,请检查网络是否已连接')
    }
  } else {
    const status = error.response.status
    switch (status) {
      // 401 未登录
      case 401:
        break
      case 403:
        break
      case 404:
        Toast({
          message: '网络请求不存在',
          duration: 1500
        })
        console.log('网络请求不存在')
        break
      default:
        Toast({
          message: error.response.data || error.response.data.message,
          duration: 1500
        })
        console.log(error.response.data.message)
    }
  }
  // 对响应错误做点什么
  return Promise.reject(error)
}
// 响应拦截器
mallAxios.interceptors.response.use(resIntercept, resErrorIntercept)

/**
 * 处理code 为 1001 会员卡购买跳转 1004 商家过期等
 * @Date 2019/11/13
 * @param data
 */
function handleErrCode(data) {
  // code==1 status=500 服务器错误
  if (data.code === 1) {
    Toast({
      message: data.message,
      duration: 1500
    })
    return false
  }
  if (data.code === -98) {
    router.push(`/bus-expires`)
  }
  // -100 表示未登录,请授权 -101 没绑定电话要绑定电话
  if (data.code === -100) {
    // 清除token
    storage.remove('token')
    store.dispatch('getAuthor')
    return false
  }
  if (data.code === -101) {
    store.commit('showPhoneDialog', true)
    return false
  }
  // 添加全局报错处理
  if (data.code !== 0 && data.code !== 10700 && data.code !== 10800) {
    Toast(data.message)
    return false
  }
  return true
}
// 简化get请求
// get, delete请求所需的参数跟post, put等不一样, 需要单独处理, 具体请参考axios文档
export let get = async (url = '', params = {}, config = {}) => mallAxios.get(url, {
  params,
  ...config
})

// 简化post请求
export let post = async (url = '', params = {}, config = {}) => mallAxios.post(url, params, config)

5. H5请求微信授权登录,调用微信JS-SDK,实现图片预览放大,分享和保存,使用微信的拍照,选图,语音,位置等手机系统功能。

// wxSdk.js
import {
  request
} from './service.js'
import wx from 'weixin-js-sdk'
export default function getWXSign(busId, url, isHideMenuItems) {
  return new Promise((resolve, reject) => {
    request.getWXConfig({ // 这是请求后台的地址
      busId,
      url
    })
      .then(function (res) {
        if (res.code === 0 && res.data) {
          const data = res.data // 返回wx.config需要的参数
          let jsApiList = ['updateAppMessageShareData', 'updateTimelineShareData', 'chooseImage', 'previewImage', 'hideAllNonBaseMenuItem', 'showAllNonBaseMenuItem', 'getLocation', 'openLocation']
          if (isHideMenuItems) jsApiList = ['hideMenuItems']
          wx.config({
            debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
            appId: data.appId, // 必填,企业号的唯一标识,此处填写企业号corpid
            timestamp: data.timestamp, // 必填,生成签名的时间戳
            nonceStr: data.nonceStr, // 必填,生成签名的随机串
            signature: data.signature, // 必填,签名,见附录1
            jsApiList // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
          })
        } else {
          resolve(res)
          return
        }
        wx.ready(function () {
          resolve(res)
        })
        wx.error(function (res) {
          resolve(res)
          // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
        })
      })
      .catch(function (error) {
        reject(error)
      })
  })
}

// 隐藏所有非基础按钮接口
// wx.hideAllNonBaseMenuItem();
// “基本类”按钮详见附录3

// 显示所有功能按钮接口
// wx.showAllNonBaseMenuItem();