目录
- 检测当前运行环境
- 时间戳转日期
- 深拷贝&浅拷贝
- 数组对象去重
- map遍历
- array 常用操作 & sort排序
- 常用正则 & 身份证验证及获取年龄
- 计算日期间隔
- android事件 屏幕闪屏
- 减少使用全局变量方法
- 判定this指向
跳转锚点平滑
// 跳转锚点 平滑
function goTarget(target) {
var timer = null;
var lastPos = 0;
function goMove() {
var currentPosition = document.documentElement.scrollTop || document.body.scrollTop;
currentPosition = parseInt(currentPosition)
if(lastPos == currentPosition) { //页面高度不够长,未滑动到指定位置的时候,已经滑动到底部了
window.scrollTo(0, target);
clearInterval(timer);
console.log('move to ' + target);
return;
}
lastPos = currentPosition;
// console.log(target, currentPosition);
if(Math.abs(currentPosition - target) < 20) {
window.scrollTo(0, target);
clearInterval(timer);
return;
}
if (currentPosition -target > 20) {
currentPosition -= 20;
window.scrollTo(0, currentPosition);
} else {
currentPosition += 20;
window.scrollTo(0, currentPosition);
}
}
timer = setInterval(goMove, 10);
}
监听input输入完成时
var cpLock = true;
$('.textrareas').on('compositionstart', function () { //输入中
cpLock = false;
});
$('.textrareas').on('compositionend', function () {//输入结束
cpLock = true;
})
检测当前运行环境
var u = navigator.userAgent, app = navigator.appVersion;
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //g
var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
if(isIOS){
}
if(isAndroid){
}
function IsPC() { // pc检测
var userAgentInfo = navigator.userAgent;
var Agents = ["Android", "iPhone",
"SymbianOS", "Windows Phone",
"iPad", "iPod"];
var flag = true;
for (var v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = false;
break;
}
}
return flag;
}
function isWeiXin(){ // 微信环境
var ua = window.navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i) == 'micromessenger'){
return true;
}else{
return false;
}
}
时间戳转日期
/**
* 时间戳转换日期
* @param <int> unixTime 待时间戳(秒)
* @param <bool> isFull 返回完整时间(Y-m-d 或者 Y-m-d H:i:s)
* @param <int> timeZone 时区
*/
var UnixToDate = function (unixTime, isFull, timeZone) {
if (typeof (timeZone) == 'number'){
unixTime = parseInt(unixTime) + parseInt(timeZone) * 60 * 60;
}
var time = new Date(unixTime * 1000);
var ymdhis = "";
ymdhis += time.getUTCFullYear() + "-";
ymdhis += ((time.getMonth()+1) >= 10 ? time.getMonth()+1 : '0'+(time.getMonth()+1)) + "-";
ymdhis += time.getDate() >= 10 ? time.getDate() : '0'+time.getDate();
if (isFull === true){
ymdhis += " " + (time.getHours() >=10 ? time.getHours() : '0'+time.getHours()) + ":";
ymdhis += (time.getMinutes() >=10 ? time.getMinutes() : '0'+time.getMinutes())+ ":";
ymdhis += (time.getSeconds() >= 10 ? time.getSeconds() : '0'+time.getSeconds());
}
return ymdhis;
}
检测变量类型
Object.prototype.toString.call(result);// 检测变量类型
判断数组类型 var arr=[]; arr instanceof Array;
JavaScript 深拷贝 浅拷贝
// 深拷贝 浅拷贝
1. 数组
let arr=[1,2,34,5,6]
let arr2=arr
arr2[1]='test'
console.log(arr) //1,'test',34,5,6
console.log(arr2) //1,'test',34,5,6
//上述属于浅拷贝
//深拷贝
let arr3=arr.slice(0) //arrayObj.slice(start, [end]) 该方法返回一个 Array 对象,其中包含了 arrayObj 的指定部分。不会改变原数组
//或者 let arr3=arr.concat()
arr3[1]='test'
console.log(arr) //1,2,34,5,6
console.log(arr3) //1,'test',34,5,6
//2. 对象
1.深拷贝
let obj={
name:'test',
age:22
}
var deepCopy = function (source) {
var result = {};
for(var key in source) {
if(typeof source[key] === 'object') {
result[key] = deepCopy(source[key])
} else {
result[key] = source[key]
}
}
return result;
}
var objCopy = deepCopy(obj)
objCopy.name="WK"
console.log(obj) //{name: "test", age: 22}
console.log(objCopy) //{name: "WK", age: 22}
2. 数组对象深拷贝
// 深拷贝
var deepCopy = function (o) {
if (o instanceof Array) {
var n = [];
for (var i = 0; i < o.length; ++i) {
n[i] = deepCopy(o[i]);
}
return n;
} else if (o instanceof Object) {
var n = {}
for (var i in o) {
n[i] = deepCopy(o[i]);
}
return n;
} else {
return o;
}
}
JavaScript 数组对象去重
<!--删除指定元素-->
arr.splice(arr.findIndex(item => item.id == id), 1)
let data = [
{ id: 201801, name: '张三', age: 15, },
{ id: 201804, name: 'John', age: 18, },
{ id: 201802, name: '李四', age: 18, },
{ id: 201801, name: '张三', age: 15, },
{ id: 201805, name: 'Jack', age: 18, },
{ id: 201803, name: '王五', age: 10, },
{ id: 201805, name: 'Jack', age: 18, },
{ id: 201804, name: 'John', age: 18, },
{ id: 201805, name: 'Jack', age: 18, },
];
let hash = {};
data = data.reduce((preVal, curVal) => {
hash[curVal.id] ? '' : hash[curVal.id] = true && preVal.push(curVal);
return preVal
}, [])
console.log(Object.keys(data)) //下标
console.log(data,hash)
数组去重
//set 方法去重
[... new Set(confimList)]
// 获取两数组交集并且保持结果元素唯一
var arr1=['0','3','5','5','6'],arr2=['4','8','10','5','5'];
var arr3 = arr2.filter(function(v){
return arr1.indexOf(v)!==-1 // 利用filter方法来遍历是否有相同的元素
})
console.log([... new Set(arr3)])// 5
map操作
let arr=[{name:'nk'},{name:"wk"},{name:'mk'},{name:"bk"}]
let array=[]
array=arr.map(res=>{
console.log(res)
return res
}) // 需要return 不然是 undefined
console.log(array)
array 操作
- 常用方法
let list=[1,2,4,5,6,7]
list.splice(num, 1) // 删除指定下标项 并返回新的数组
list.shift(); //删除第一项
list.unshift() ;// 将某值添加到数组开头
list.pop();// 删除最后一项
list.push();// 添加到数组后
list.concat();// 拼接数组
//、、、splice操作、、、
var a = [1,2,3,4,5];
var b = a.splice(2,2,7,8,9); //a:[1,2,7,8,9,5] b:[3,4]
var b = a.splice(0,1); //同shift
a.splice(0,0,-2,-1); var b = a.length; //同unshift
var b = a.splice(a.length-1,1); //同pop
a.splice(a.length,0,6,7); var b = a.length; //同push
list.reverse();//反序
list.slice(start,end):返回从原数组中指定开始下标到结束下标之间的项组成的新数组
list.join(separator):将数组的元素组起一个字符串,以separator为分隔符,省略的话则用默认用逗号为分隔符
- sort 排序
let arr = [11, 2, 13, 5, 7, 8]
arr.sort((x, y) => {
if(x<y){ //降序 x>y 升序
return 1
}
// return 0
// console.log(y)
})
console.log(arr)
// 按照字母排序 a-z
var list = [{name:'Google'},{name:'apple'},{name: 'Microsoft'}];
list.sort((a,b)=>a.name.localeCompare(b.name,'zh'))
常用正则验证
//Email正则
var ePattern = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
用法:ePattern.test("99154507@qq.com") true
.replace(/(^\s*)/g,"") // 删除空格
// 正则验证
var myreg = /^1[345678]\d{9}$/; //手机号码验证
var nameReg = /^[A-Za-z\/\u4e00-\u9fa5]+$/; //姓名验证
var reg = /^[0-9a-zA-Z]+$/; //只能输入字母和数字data
!myreg.test('29301938')//使用方法
//身份证 验证
checkIDCard(idcode) {
// 加权因子
var weight_factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
// 校验码
var check_code = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
var code = idcode + "";
var last = idcode[17];//最后一个
var seventeen = code.substring(0, 17);
// ISO 7064:1983.MOD 11-2
// 判断最后一位校验码是否正确
var arr = seventeen.split("");
var len = arr.length;
var num = 0;
for (var i = 0; i < len; i++) {
num = num + arr[i] * weight_factor[i];
}
// 获取余数
var resisue = num % 11;
var last_no = check_code[resisue];
// 格式的正则
// 正则思路
/*
第一位不可能是0
第二位到第六位可以是0-9
第七位到第十位是年份,所以七八位为19或者20
十一位和十二位是月份,这两位是01-12之间的数值
十三位和十四位是日期,是从01-31之间的数值
十五,十六,十七都是数字0-9
十八位可能是数字0-9,也可能是X
*/
var idcard_patter = /^[1-9][0-9]{5}([1][9][0-9]{2}|[2][0][0|1][0-9])([0][1-9]|[1][0|1|2])([0][1-9]|[1|2][0-9]|[3][0|1])[0-9]{3}([0-9]|[X])$/;
// 判断格式是否正确
var format = idcard_patter.test(idcode);
// 返回验证结果,校验码和格式同时正确才算是合法的身份证号码
return last === last_no && format ? true : false;
} // 返回 true false
// 根据身份证号得到姓别和精确计算年龄
function analyzeIDCard(IDCard,date) {
var sexAndAge = {};
//获取用户身份证号码
var userCard = IDCard;
//如果身份证号码为undefind则返回空
if (!userCard) {
return sexAndAge;
}
//获取性别
if (parseInt(userCard.substr(16, 1)) % 2 == 1) {
sexAndAge.sex = '1(男)'
} else {
sexAndAge.sex = '0(女)'
}
//获取出生年月日
//userCard.substring(6,10) + "-" + userCard.substring(10,12) + "-" + userCard.substring(12,14);
var yearBirth = userCard.substring(6, 10);
var monthBirth = userCard.substring(10, 12);
var dayBirth = userCard.substring(12, 14);
//获取当前年月日并计算年龄
var myDate = new Date(date);
var monthNow = myDate.getMonth() + 1;
var dayNow = myDate.getDay();
var age = myDate.getFullYear() - yearBirth;
if (monthNow < monthBirth || (monthNow == monthBirth && dayNow < dayBirth)) {
age--;
}
//得到年龄
sexAndAge.age = age;
//返回性别和年龄
return sexAndAge;
}
计算日期间隔
// 计算 出发日期和到达日期相差几天
function DateDiff(sDate1, sDate2) { //sDate1和sDate2是yyyy-MM-dd格式
var dateSpan,
tempDate,
iDays;
sDate1 = Date.parse(sDate1);
sDate2 = Date.parse(sDate2);
dateSpan = sDate2 - sDate1;
dateSpan = Math.abs(dateSpan);
iDays = Math.floor(dateSpan / (24 * 3600 * 1000));
return iDays; //返回相差天数
}
倒计时
由于要获取时间戳 this.data.actEndTime格式最好为 :2019/02/12
countDown() {//倒计时函数
// 获取当前时间,同时得到活动结束时间数组
let newTime = new Date().getTime();
let endTimes = this.data.actEndTime; // 结束日期
let countDownArr;
// 对结束时间进行处理渲染到页面
let endTime = new Date(endTimes).getTime();
let obj = null;
// 如果活动未结束,对时间进行处理
if (endTime - newTime > 0) {
let time = (endTime - newTime) / 1000;
// 获取天、时、分、秒
let day = parseInt(time / (60 * 60 * 24));
let hou = parseInt(time % (60 * 60 * 24) / 3600);
let min = parseInt(time % (60 * 60 * 24) % 3600 / 60);
let sec = parseInt(time % (60 * 60 * 24) % 3600 % 60);
obj = {
day: this.timeFormat(day),
hou: this.timeFormat(hou),
min: this.timeFormat(min),
sec: this.timeFormat(sec)
}
} else {//活动已结束,全部设置为'00'
obj = {
day: '00',
hou: '00',
min: '00',
sec: '00'
}
}
countDownArr=obj;
// 渲染,然后每隔一秒执行一次倒计时函数
this.setData({ countDown: countDownArr })
if (countDownArr.min == '00' && countDownArr.sec== '00'){
// this.setData({status:2})
return false
}
setTimeout(this.countDown, 1000);
}
Android 手机点击事件出现闪屏
相应元素添加:-webkit-tap-highlight-color:rgba(0,0,0,0)
避免全局变量污染
一、 使用全局唯一变量
只声明一个全局变量:
var maApp={
//只要把多个全局变量都整理在同一个命名空间下,就能显著降低与其他应用程序、
//组件或类库之间产生不可预知的相互影响的可能性,也使其可读性更高。
}
二、 使用全局唯一变量
使用闭包:
///创建一个函数,该函数包括,私有变量和一个特权对象,特权对象的内容是,利用闭包能访问到私有变量的函数,最后返回特权对象
var f3 = function() {
var age = 18;
return {
name: "啊哈",
age: age,
gender: "男"
}
}();
//获取变量
f3.name = "啊哈";
// 自执行函数
/*所有代码写在其中,在它内部声明的变量全部都是局部变量
,一般用来写完全独立的脚本*/
(function() {
//我在一个匿名自执行函数中
//some code here...
})()
判定this指向
判定 this 现在,我们可以按照优先顺序来总结一下从函数调用的调用点来判定 this 的规则了。按照这个顺序来问问题,然后在第一个规则适用的地方停下。
- 函数是通过 new 被调用的吗(new 绑定)?如果是,this 就是新构建的对象。
var bar = new foo()
- 函数是通过 call 或 apply 被调用(明确绑定),甚至是隐藏在 bind 硬绑定 之中吗?如果是,this 就是那个被明确指定的对象。
var bar = foo.call( obj2 )
- 函数是通过环境对象(也称为拥有者或容器对象)被调用的吗(隐含绑定)?如果是,this 就是那个环境对象。
var bar = obj1.foo()
- 否则,使用默认的 this(默认绑定)。如果在 strict mode 下,就是 undefined,否则是 global 对象。
var bar = foo()
四种规则将会以这种优先顺序施用于调用点:
通过 new 调用?使用新构建的对象。
通过 call 或 apply(或 bind)调用?使用指定的对象。
通过持有调用的环境对象调用?使用那个环境对象。
默认:strict mode 下是 undefined,否则就是全局对象。
小心偶然或不经意的 默认绑定 规则调用。如果你想“安全”地忽略 this 绑定,一个像 ø = Object.create(null) 这样的“DMZ”对象是一个很好的占位值,以保护 global 对象不受意外的副作用影响。
与这四种绑定规则不同,ES6 的箭头方法使用词法作用域
来决定 this 绑定,这意味着它们采用封闭他们的函数调用作为 this 绑定(无论它是什么)。它们实质上是 ES6 之前的 self = this 代码的语法替代品。
以上,就是理解对于普通的函数调用来说的 this 绑定规则 所需的全部。