js 常用功能、方法实现(函数)
1、10 个短小实用的代码片段 : https://www.jianshu.com/p/3ef822ec5a63
2、js常用函数 : https://www.cnblogs.com/wangyuyuan/p/8807765.html (原生实现)
/** * 导入文件内方法 */ import Promise from './es6-promise.min.js'; import CONSTANTS from '../constants/constants.js'; /** * 操作dom类 */ let dom = { // 判断是否有该 class hasClass(el, className) { let reg = new RegExp('(^|\\s)' + className + '(\\s|$)') return reg.test(el.className) }, // 添加 class addClass(el, className) { if (this.hasClass(el, className)) { return } let newClass = el.className.split(' ') newClass.push(className) el.className = newClass.join(' ') }, // 删除类名 removeClass(el, className) { if (this.hasClass(el, className)) { var reg = new RegExp('(\\s|^)' + className + '(\\s|$)') el.className = el.className.replace(reg, '') } }, // 替换类名 replaceClass(obj, newName, oldName) { this.removeClass(obj, oldName) this.addClass(obj, newName) }, /** * 获取/设置 自定义属性 data-${name}=val * 如果传入了 val 就设置自定义属性 `data-${name}` 的值为 val * 如果没有传入了 val 就获取自定义属性 `data-${name}` 的值 */ customAttribute(el, name, val) { if (val) { return el.setAttribute(`data-${name}`, val) } else { return el.getAttribute(`data-${name}`) } }, /** * 获取元素相对屏幕的位置 * let one = document.getElementById('one') * console.log(getPos(one)) -> {top: 8, left: 8} */ getPos(elem) { if (!elem) return { left: 0, top: 0 } let top = 0 let left = 0 top = elem.getBoundingClientRect().top left = elem.getBoundingClientRect().left return { top, left } } } /*** * 操作数组类 */ let arr = { // 克隆数组 cloneArr(arr) { // 从第一个字符就开始 copy // slice(start,end) 方法可从已有的数组中返回选定的元素。 return arr.slice(0) }, /** * 洗牌函数 * @param {Array} arr 原数组 * @param {boolean} flag 是否改变原数组,默认不改变 * @return {Array} 新数组 */ shuffle(arr, flag = false) { let newArr = [] if (flag) { newArr = arr } else { newArr = arr.slice(0) } for (let i = 0; i < newArr.length; i++) { let j = utils.num.getRandom(0, i) let temp = newArr[i] newArr[i] = newArr[j] newArr[j] = temp } return newArr }, // 随机获取数组的一个成员 randomOne(arr) { return arr[Math.floor(Math.random() * arr.length)] }, // 数组去重 removeRepeat(arr) { return Array.from(new Set(arr)) }, // [1,2,3,1,'a',1,'a'].filter(function(ele,index,array){ // return index===array.indexOf(ele) // }) // 数组最大值 maxArr(arr) { return Math.max.apply(null, arr) // var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411]; // var maxInNumbers = Math.max.apply(Math, numbers); // var minInNumbers = Math.min.apply(Math, numbers); }, // 数组最小值 minArr(arr) { return Math.min.apply(null, arr) }, // 数组数字总和 (必须保证数组每个元素都是 Number) sumArr(arr) { let sum = 0 for (let i = 0; i < arr.length; i++) { sum += arr[i] } return sum }, // 数组数字平均值,小数点可能会有很多位,这里不做处理,处理了使用就不灵活了! averageArr(arr) { let average = this.sumArr(arr) / arr.length return average }, /** * 一个元素出现的次数 * getEleCount('asd56+asdasdwqe', 'a') -> 3 * getEleCount([1, 2, 3, 4, 2], 3) -> 1 * @param {[type]} obj 可以是对象或者数组 * @param {[type]} ele [description] * @return {[type]} [description] */ getEleCount(obj, ele) { let num = 0 for (let i = 0; i < obj.length; i++) { if (ele === obj[i]) { num++ } } return num } } /** * 操作字符串类 */ let str = { /** * 正则验证(可扩展) * @param {String} str 需要检测的字符串 * @param {String} type 检测类型 * @return {Boolean} 返回布尔值 */ testReg(str, type) { switch (type) { case 'email': return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str) case 'phone': return /^1[3|4|5|7|8][0-9]{9}$/.test(str) case 'tel': return /^(0\d{2,3}-\d{7,8})(-\d{1,4})?$/.test(str) case 'number': return /^[0-9]$/.test(str) case 'english': return /^[a-zA-Z]+$/.test(str) case 'chinese': return /^[\u4E00-\u9FA5]+$/.test(str) case 'lower': return /^[a-z]+$/.test(str) case 'upper': return /^[A-Z]+$/.test(str) default: return true } }, /** * 去掉前后空格 * 1:前后空格(默认) 2:所有空格 3:前空格 4:后空格 * @param {[type]} str [description] * @param {Number} type [description] * @return {[type]} [description] */ trim(str, type = 1) { switch (type) { case 1: return str.replace(/(^\s*)|(\s*$)/g, '') case 2: return str.replace(/\s+/g, '') case 3: return str.replace(/(^\s*)/g, '') case 4: return str.replace(/(\s*$)/g, '') default: return str } }, /** * 大小写转换 * 1:首字母大写 2:首页母小写 3:大小写转换 4:全部大写 5:全部小写 */ changeCase(str, type) { function ToggleCase(str) { var itemText = '' str.split('').forEach( function (item) { if (/^([a-z]+)/.test(item)) { itemText += item.toUpperCase() } else if (/^([A-Z]+)/.test(item)) { itemText += item.toLowerCase() } else { itemText += item } }) return itemText } switch (type) { case 1: return str.replace(/^(\w)(\w+)/, function (v, v1, v2) { return v1.toUpperCase() + v2.toLowerCase() }) case 2: return str.replace(/^(\w)(\w+)/, function (v, v1, v2) { return v1.toLowerCase() + v2.toUpperCase() }) case 3: return ToggleCase(str) case 4: return str.toUpperCase() case 5: return str.toLowerCase() default: return str } }, /** * 如何优雅的实现金钱格式化 * 1234567890 --> 1,234,567,890 * @return {[type]} [description] */ formatMoney(str = '1234567890') { return str.replace(/\B(?=(\d{3})+(?!\d))/g, ',') // 1,234,567,890 }, /** * 实现标准JSON的深拷贝 * 不考虑IE的情况下,标准JSON格式的对象蛮实用,不过对于undefined和function的会忽略掉。 * @param {[type]} a [description] * @return {[type]} [description] */ deepCopy(a) { return JSON.parse(JSON.stringify(a)) } } /** * 操作时间类 */ let time = { /** * 获取当前时间 * 2017-08-11 22:52:13 星期六 * @param {Boolean} hasDay 是否需要年月日 * @param {Boolean} hasHour 是否需要十分秒 * @param {Boolean} hasWeek 是否需要星期 * @param {String} sign1 分隔符 * @param {String} sign2 分隔符 */ getNowDate(hasDay = true, hasHour = true, hasWeek = true, sign1 = '/', sign2 = ':') { let date = new Date() let year = date.getFullYear() let month = (date.getMonth() + 1).toString().padStart(2, '0') let day = (date.getDate()).toString().padStart(2, '0') let hour = (date.getHours()).toString().padStart(2, '0') let minutes = (date.getMinutes()).toString().padStart(2, '0') let seconds = (date.getSeconds()).toString().padStart(2, '0') let weekArr = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期天'] let week = weekArr[date.getDay()] let time1 = hasDay ? `${year}${sign1}${month}${sign1}${day}` : '' let time2 = hasHour ? `${hour}${sign2}${minutes}${sign2}${seconds}` : '' let time3 = hasWeek ? `${week}` : '' return `${time1} ${time2} ${time3}`.replace(/(^\s*)|(\s*$)/g, '') }, /** * 格式化时间戳 (分:秒) * 61 -> 01:01 * @param {Number} timestamp 时间戳 * @param {String} sign 分隔符,默认 : * @return {[type]} [description] */ format(timestamp, sign = ':') { timestamp = Math.floor(timestamp) let minute = (Math.floor(timestamp / 60)).toString().padStart(2, '0') let second = (timestamp % 60).toString().padStart(2, '0') return `${minute}${sign}${second}` }, /** * 倒计时 * countDown('2017-8-11 24:0:0') -> 剩余0天0小时54分钟41秒 * @param {Date} endTime 结束时间 * @return {[type]} [description] */ countDown(endTime) { let start = new Date() let end = new Date(endTime) let dif = end.getTime() - start.getTime() let d = 0 let h = 0 let m = 0 let s = 0 if (dif >= 0) { d = Math.floor(dif / 1000 / 3600 / 24) h = Math.floor(dif / 1000 / 60 / 60 % 24) m = Math.floor(dif / 1000 / 60 % 60) s = Math.floor(dif / 1000 % 60) } return `仅剩${d}天${h}小时${m}分钟${s}秒` } } /** * 请求接口类 */ let ajax = { /** * 请求接口方法 * @param{url}请求url * @param{method} 请求方式 * @param{data} 请求参数 */ brmRequest(url, method, data) { let token = wx.getStorageSync('AuthToken'); return new Promise((resolve, reject) => { wx.request({ url, method, data, header: { 'Cookie': 'XDEBUG_SESSION=PHPSTORM', 'Content-Type': 'application/json', 'Authorization': token }, success: function (res) { if (res.header.Authorization && token != res.header.Authorization) { wx.setStorageSync('AuthToken', res.header.Authorization) } resolve(res.data); }, fail: function (err) { reject(err); } }); }) } } //导出方法类 module.exports = { dom: dom, arr: arr, str: str, time: time, ajax: ajax, }
3、快速创建一个 对象的数组:【做模拟数据的时候回经常用到,20-30条这样的数据,看页面的效果】
实现思路:基于一个现有数组,进行遍历(推荐这种,快速) 或 for循环 给数组添加数据。
let arr = new Array(20) let arr2 = Array.from(arr, () => { return{ groupId: 'xxxxx', personNum: '12', casesTimes: '20', involveFeeMed: '¥8,888', involveFeeFund: '¥8,888', digDate: '2019-01-01', recentDate: '2019-01-01', } })
4、将 js 对象,拼接成 请求参数显示。原生的ajax请求参数都是 key1=value1&key2=value2 这种显示的。所以需要这样一个方法就像处理函数。 参考链接
// 格式化参数 function formatParams (data) { var arr = [] for (var item in data) { arr.push(item + '=' + data[item]) } return arr.join('&') }
5、数组去重:https://segmentfault.com/a/1190000016418021
[...new Set(arr)] // 最简单的方法
6、字符串去除两边空格:
7、获取 url上 的参数(包括 # 号后面的参数):
const getQueryString = function (name) { let regUrl = new RegExp(name + '=') let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i') let url = location.href let urlSerch = location.search let urlHash = location.hash // 获取url 上的authcode参数值,因为不知道参数是在#前还是#号后。所以要对location.search和location.hash分开判断 if (!regUrl.test(url)) { return null } let queryStr = urlSerch.substr(1).match(reg) || urlHash.split('?')[1].match(reg) if (queryStr != null) { return unescape(queryStr[2]) } return null }
8、JS 解析URL 字符串,变成一个URL 对象:
https://www.cnblogs.com/qiuxiaozhen/p/10520300.html (通过创建 a 标签 实现,url上的所有属性都挂在a对象下面,如 host值: a.hostname ) 或
https://www.jb51.net/article/157127.htm (通过新的 URL 构造函数实现) 或
https://www.cnblogs.com/chanruida/archive/2012/05/16/2505544.html (使用正则,通过 字符串 拆解 实现)
9、判断JS对象是否拥有某属性:https://blog.csdn.net/lianjiuxiao/article/details/88819773
注意 :js中变量 不可用来调用方法(或属性)的值的值有 undefined(声明未赋值)、null、''(初始化的值)、NaN(计算后产生的值,一般判断是否有值不用判断它)。这些值,调用方法或属性,浏览器就不会报错。