javascript功能封装
实现方式其实很简单,我在代码打上注释,大家就懂了!
var _date=[],dateData=["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"];//准备一个月份反转的数组var dateDataRet=Object.assign([],dateData).reverse();//获取当前年份var yearText=new Date().getFullYear();//获取当前月份 调试的时候,大家可以通过调整now调试 3月-now=2,12月now=11...var now=new Date().getMonth();for(let i=0;i<6;i++){if(now-i<0){//如果now-i<0,从dateDataRet里面拿数据,下标=|now-i|-1。_date.push(yearText-1+'年'+dateDataRet[Math.abs(now-i)-1]);}else{//从dateData里面拿数据,下标=now-i_date.push(yearText+'年'+dateData[now-i]);}}_date.reverse();
可能大家看着会懵,直接看下面的循环图就懂了
3.数值区间
如下图,就是几个数值区间,而且会有一个最小值和最大值
var _min=5,_max=50;function checkArr(arr,min,max){//排序arr.sort(function(n1,n2){return n1.min-n2.min})//遍历for(var i=0;i<arr.length;i++){//区间的最小值不能大于等于区间最大值if(arr[i].min>=arr[i].max){console.log('区间的最小值不能大于等于区间最大值');return;}//区间的最小值不能小于默认最小值if(arr[i].min<min){console.log('区间的最小值不能小于默认最小值');return;}//区间的最大值不能大于默认最大值if(arr[i].max>max){console.log('区间的最大值不能大于默认最大值');return;}//元素对比,从第二个元素开始if(i>0){//minInclude,maxInclude,为false就是不包含,为true就是包含//{min:10,max:20,minInclude:false,maxInclude:false}//等同于(10,20)//{min:20,max:30,minInclude:true,maxInclude:false}//等同于[20,30);//如果前一个的最大值和当前的最小值都是包含情况,那么当前区间的最小值一定要比前一个区间的最大值大1if(arr[i].minInclude&&arr[i-1].maxInclude&&arr[i].min-arr[i-1].max!==1){console.log('取值范围错误-当前区间的最小值和前一个区间的最大值都是包含情况,当前区间的最小值一定要比前一个区间的最大值大1');return;}//如果前一个的最大值和当前的最小值。一个是包含,一个是不包含,那么当前区间的的最小值一定要等于上一个区间的最大值else if(arr[i].minInclude!==arr[i-1].maxInclude&&arr[i].min!==arr[i-1].max){console.log('取值范围错误-当前区间的最小值和前一个区间的最大值其中一个是包含,一个是不包含情况,当前区间的最小值一定要等于前一个区间的最大值');return;}//如果前一个的最大值和当前的最小值都是不包含,肯定不满足else if((!arr[i].minInclude)&&(!arr[i-1].maxInclude)){console.log('取值范围错误-前一个的最大值和当前的最小值都是不包含情况,不满足收尾相连');return;}}}}
测试用例
var arr1=[{min:10,max:20,minInclude:false,maxInclude:true},{min:21,max:30,minInclude:true,maxInclude:true}],arr2=[{min:10,max:20,minInclude:false,maxInclude:true},{min:20,max:30,minInclude:true,maxInclude:false}],arr3=[{min:10,max:20,minInclude:false,maxInclude:true},{min:20,max:30,minInclude:false,maxInclude:false}],arr4=[{min:10,max:20,minInclude:false,maxInclude:false},{min:20,max:30,minInclude:true,maxInclude:false}],arr5=[{min:10,max:20,minInclude:false,maxInclude:false},{min:21,max:30,minInclude:true,maxInclude:false}],arr6=[{min:10,max:20,minInclude:false,maxInclude:false},{min:15,max:30,minInclude:false,maxInclude:false}],arr7=[{min:10,max:20,minInclude:false,maxInclude:false},{min:20,max:30,minInclude:false,maxInclude:false}],arr8=[{min:1,max:20,minInclude:false,maxInclude:false},{min:20,max:30,minInclude:false,maxInclude:false}],arr9=[{min:20,max:20,minInclude:false,maxInclude:false},{min:20,max:30,minInclude:false,maxInclude:false}],arr10=[{min:20,max:30,minInclude:false,maxInclude:false},{min:20,max:70,minInclude:false,maxInclude:false}];
运行结果
4.数组对比
这个基于我回答过的一个问题,现在化用,改写一下
JavaScript如何对比两个数组?数组B根据数组A来做出增删? (不用jquery,原生js)
具体问题是这样的:
arryA
var arrayA = ['a','b','c'];
arryB
var arrayB = [{key:'a',num1:'1',num2:'2',num3:'3',tot:'6'},{key:'b',num1:'11',num2:'22',num3:'33',tot:'66'},{key: 'c',num1: '111',num2: '222',num3: '333',tot:666}];
1、如果arryA中有a,arryB中没有,那么在arryB中增加一个key值为a的boj,且其他属性值可均为'0';如下: {key:'a',num1:'0',num2:'0',num3:'0',tot':0'}
2、如果arryA中有a,arryB中也有key值为a的obj,那么arryB则不改变,并且该obj里的其他属性和属性值均不变;
3、如果在arryA中删除了a,那么arryB中key值为a的obj整个删掉。
//准备临时数组function compareArr(arr1,arr2){var result=[],arr;//遍历for(var i=0;i<arr1.length;i++){//根据arr1[i]的值,查找arrayB,如果arr2中的有满足条件(arrayB中的对象,有key值等于arrayA[i])的项,就会返回满足条件的项,否则返回underfind;arr=arr2.find(function(val){return val.key===arr1[i]});//如果arr不是undefind,就会添加arr,否则添加{key:arrayA[i],num1:'0',num2:'0',num3:'0',tot:'0'}。arr?result.push(arr):result.push({key:arrayA[i],num1:'0',num2:'0',num3:'0',tot:'0'});}}
测试
var arrayA = ['b','c'];var arrayB = [{key:'a',num1:'1',num2:'2',num3:'3',tot:'6'},{key:'b',num1:'11',num2:'22',num3:'33',tot:'66'},{key: 'c',num1: '111',num2: '222',num3: '333',tot:666}];compareArr(arrayA,arrayB);
5.学院获奖
统计学生申请优秀毕业生,并且符合条件的(成绩优秀,拿过奖学金,获得过三好学生)。前提是要申请
大概的流程图就是像下面这样!
我在代码上写上注释,相信不难理解了
//学生列表//isApply:是否有申请优秀毕业生let studentList = [{name: 'aa',isApply: false,id: 1},{name: 'bb',isApply: true,id: 2},{name: 'cc',isApply: true,id: 3}];//申请优秀毕业生的学生 isApply:truelet _student = studentList.filter(function (item) {return item.isApply;});//isExcellent:优秀学生的id列表//isScholarship:获得过奖学金的学生的id列表//isThreeGood:获得过三好学生的学生的id列表//accord:集合let isExcellent = [1, 2, 3, 4, 5], isScholarship = [4, 2, 5, 6, 2, 1, 2], isThreeGood = [2, 1, 4, 52, 36], accord = [];//数组去重函数function removeRepeatArr(arr) {return arr.filter(function (item, index, self) {return self.indexOf(item) === index;});}//统计数组中,一个遇上元素的出现次数function getEleCount(obj, ele) {let num = 0;for (let i = 0, len = obj.length; i < len; i++) {if (ele === obj[i]) {num++;}}return num;}//添加学生记录,把获得成绩优秀的学生的id,获得过奖学金的学生的id,获得过三好学生的id添加进去。//但是添加之前,要对获得成绩优秀的学生的id,获得过奖学金的学生的id,获得过三好学生的id。这个三个数组进行去重再添加进accord,因为一个学生可能不止一次成绩优秀,不止一次获得过奖学金,不止一次获得过三好学生//这样就方便下面的判断,只要学生的id在accord里面出现两次及以上就符合条件accord.push.apply(accord, removeRepeatArr(isExcellent));accord.push.apply(accord, removeRepeatArr(isScholarship));accord.push.apply(accord, removeRepeatArr(isThreeGood));console.log(accord);//符合条件的学生列表let accordStudent = [];for (let i = 0; i < _student.length; i++) {//只要学生的id在accord里面出现两次及以上if (getEleCount(accord, _student[i].id) >= 2) {//记录哪些学生符合条件accordStudent.push(_student[i]);}}console.log(accordStudent);
6.数组连续的最大长度
这个也是出于我回答过的问题:如下
//假如有一个数组,下面这个数组最大的连续长度就是4——————8,9,10,11var arr=[1,2,4,5,6,8,9,10,11];//代码实现function countLen(arr){//如果参数不是数组或者长度为0,直接返回0if(arr.constructor!==Array||arr.length===0){return 0;}//首先进入当前连续长度nowLen设初始化为1,最大连续长度maxLen初始化为0var nowLen=1,maxLen=0;for(var i=1,len=arr.length;i<len;i++){//当前数组元素是不是比上一个数组大1if(arr[i]-arr[i-1]===1){//如果是,当前连续长度nowLen+1nowLen++;}else{//否则先判断,当前连续长度是否大于最大连续长度if(maxLen<nowLen){//如果是就赋值maxLen=nowLen}//当前连续长度初始化为1nowLen=1;}}//循环完再判断一次当前连续长度是否大于最大连续长度(避免最大连续长度是数组最后面几个数组时产生的bug)if(maxLen<nowLen){maxLen=nowLen}//返回最大连续长度return maxLen;}
7.答题连对数
这个和上面的代码基本一样,只是判断条件毫厘之差,直接贴,大家看就好
function countTrue(arr){debugger;//如果参数不是数组或者长度为0,直接返回0if(arr.constructor!==Array||arr.length===0){return 0;}//首先初始化连续答对长度nowLen为0,最大连续答对长度maxLen为0var nowLen=0,maxLen=0;for(var i=0,len=arr.length;i<len;i++){//当前数组元素是不是比上一个数组大1if(arr[i]){//如果是,当前连续长度nowLen+1nowLen++;}else{//否则先判断,当前连续长度是否大于最大连续长度if(maxLen<nowLen){//如果是就赋值maxLen=nowLen}//当前连续长度初始化为0nowLen=0;}}//循环完再判断一次当前连续长度是否大于最大连续长度(避免最大连续长度是数组最后面几个数组时产生的bug)if(maxLen<nowLen){maxLen=nowLen}//返回最大连续长度return maxLen;}
8.命名方式转换
比如驼峰命名方式转'-'命名方式。
var str = "shouHou";//$1-第一个括号匹配的内容//这个实例,$1='H'str = str.replace(/([A-Z])/g,"-$1").toLowerCase();
比如'-'命名方式转驼峰命名方式
var str="shou-hou";//$0-匹配的结果 $1-第一个括号匹配的内容//这个实例$0='-h' $1='h'str=str.replace(/-(\w)/g,function($0,$1){return $1.toUpperCase();});
9.格式化字符
这个最常见的就是在金额方面的显示需求上,比如后台返回10000。前端要显示成10,000或者其他格式等!
//str//size-每隔几个字符进行分割 默认3//delimiter-分割符 默认','function formatText(str,size,delimiter){var _str=str.toString();var _size=size||3,_delimiter=delimiter||',';/*如果_size是3"\d{1,3}(?=(\d{3})+$)"*/var regText='\\d{1,'+_size+'}(?=(\\d{'+_size+'})+$)';/*/\d{1,3}(?=(\d{3})+$)/g 这个正则的意思:匹配连续的三个数字,但是这些三个数字不能是字符串的开头1-3个字符*/var reg=new RegExp(regText,'g');/*(-?) 匹配前面的-号 (\d+)匹配中间的数字 ((\.\d+)?)匹配小数点后面的数字//$0-匹配结果,$1-第一个括号返回的内容----(-?) $2,$3如此类推*/return _str.replace(/^(-?)(\d+)((\.\d+)?)$/, function ($0, $1, $2, $3) {return $1 + $2.replace(reg, '$&,') + $3;})}
10.对象合并,并且记录异常数据
这个需求,可能大家有点懵。下面实例分析 比如有两个都地方记录了我的信息
let info1={name:"守候",sex:"男",age:24,job:"web前端"},info2={name:"守候!",country:"china",interest:"basketball",phone:"12345678910",job:"web前端"}
现在要合并我的信息,并且记录可能有异常的信息。比如上面的name属性,在两个对象都有,而且两个对象的值不一样,那么就不知道到底是info1中的name属性是正确的,还是info2中的name属性是正确的。所以,就得把name这个属性记录起来,方便以后核对name这个属性。
如下图
下面,一步一步来,先不管3721,直接合并属性
let objAll={};function assignObj(objArr) {let _obj={};for(let i=0;i<objArr.length;i++){_obj=Object.assign(_obj,objArr[i],{});}return JSON.parse(JSON.stringify(_obj));}objAll=assignObj([objA,objB]);
然后先准备一个字段,记录哪些异常信息
objAll.warnInfo=[];
最后检查对象,判断哪些信息有异常
function checkObj(_objAll,objList) {//获取所有属性let _keys=Object.keys(_objAll);for(let i=0;i<objList.length;i++){for(let j=0;j<_keys.length;j++){//如果_keys[j]这个属性,在objList[i]和_objAll里面都存在,而且这两个值是不一样的,那么就是一场数据,需要记录!if(objList[i][_keys[j]]!==undefined&&_objAll[_keys[j]]!==objList[i][_keys[j]]){_objAll.isError.push(_keys[j]);}}}return _objAll;}console.log(checkObj(objAll,[objA,objB]));
11.筛选标签
如下图,在下面渲染这个标签
大家可能第一可能觉得压根没难度,就是一个对象数组:比如
var searchTag=[{label:'产品编码',value:'100072236-8'},{label:'产品名称',value:'甘油'}]
但是这样的数据,显然是要经过处理生成的,因为不可能这样发送请求
http://example.com?产品编码=100072236-8
发送过去的参数应该是这样的
http://example.com?proId=100072236-8var searchParam={proId:'100072236-8',proName:'甘油'}
怎么进行数据的处理呢,其实很简单,代码不打注释,我想都看得懂
var searchTag=[];var searchText={proId:'产品编码',proName:'产品名称'};var searchParam={proId:'100072236-8',proName:'甘油'};Object.keys(searchParam).forEach(function (item) {searchTag.push({label:searchText[item],key:item,value:searchParam[item]})})console.log(searchTag)
有了这些数据,渲染到页面这个就简单了!
12.导入excel内容
就是excel上这样的内容
转成下面的数据
目录如下
下面开始写代码,我们利用node.js来写
let path = require('path');//使用ejsexcel读取excel文件 npm install ejsexcel --savelet ejsExcel=require('ejsexcel');let fs=require('fs');//读取excellet exBuf=fs.readFileSync(__dirname+'/resource/userList.xlsx');let _data=[];//获取成功后ejsExcel.getExcelArr(exBuf).then(exlJson=>{//获取excel数据let workBook=exlJson;//获取excel第一张表 sheet1let workSheets=workBook[0];//导出js的路径let newfilepath=path.join(__dirname,"/resource/test.js");//遍历第一张表的的每一行数据workSheets.forEach((item,index)=>{//从第二行开始插入,避免连表头也插入_data里面if(index>0){//往_data插入单元格个值,item[0]相当于excel中的姓名,item[1]就是excel中的联系电话_data.push({name:item[0],phone:item[1]})}});//写入js文件fs.writeFileSync(newfilepath, 'let _data='+JSON.stringify(_data)+';export {_data}');}).catch(error=>{//打印获取失败信息console.log("读取错误!");console.log(error);});
然后命令行执行该js
$ node importFile.js
然后就发现多了一个test.js文件
excel的数据就这样导入成js的一个数组了,只要引入这个数组,就可以正常的使用了!
13.随机循环
当时接到的业务是实际显示客户的信息,感觉有点像音乐播放器的随机循环。
要求:
一个提示列表里面,提示的信息每隔500ms随机展示。
同一轮循环里面,一个提示信息只能展示一次。
列表的提示信息全部展示完了,进行下一轮展示。
这个逻辑没什么,直接在代码打上注释,我想大家就明白了!
var tipList=['提示1','提示2','提示3','提示4','提示5','提示6','提示7','提示8','提示9'];var tipListShow=[];tipListShow=Object.assign([],tipList);var i=0,timer=null;function play() {//随机显示一个,显示了之后,把这个项从tipListShow中删除掉,防止在同一轮重复出现!console.log(tipListShow.splice(Math.floor(Math.random() * tipListShow.length),1)[0]);//当循环完了之后,tipListShow的长度就会是0,然后就重新赋值,准备进行下一轮的随机循环if(tipListShow.length===0){tipListShow=Object.assign([],tipList);i=0;}//如果需要暂停或者停止的,清除这个定时器即可,下次执行就重新这样创建定时器,执行play();!timer=setTimeout(function () {play();},500);}play();
javascript功能封装的更多相关文章
- 第一百三十五节,JavaScript,封装库--拖拽
JavaScript,封装库--拖拽 封装库新增1个拖拽方法 /** tuo_zhuai()方法,将一个弹窗元素实现拖拽功能 * 注意:一般需要在css文件将元素里的某一个区块光标设置成提示可以拖拽, ...
- 第一百三十三节,JavaScript,封装库--弹出登录框
JavaScript,封装库--弹出登录框 封装库,增加了两个方法 yuan_su_ju_zhong()方法,将获取到的区块元素居中到页面,chuang_kou_shi_jian()方法,浏览器窗口事 ...
- 第一百三十二节,JavaScript,封装库--下拉菜单
JavaScript,封装库--下拉菜单 封装库,增加了3个方法 shu_biao_yi_ru_yi_chu()方法,给元素设置鼠标移入移出事件,接收两个参数,参数是移入和移出时的执行函数(包含代码) ...
- 第一百三十一节,JavaScript,封装库--CSS
JavaScript,封装库--CSS 将封装库里的方法,改成了原型添加方法 增加4个方法 tian_jia_class()方法,给获取到的元素添加class属性,参数是class属性值,可以连缀1 ...
- 第一百三十节,JavaScript,封装库--连缀
JavaScript,封装库--连缀 学习要点: 1.连缀介绍 2.改写库对象 本章我们重点来介绍,在调用库的时候,我们需要能够在前台调用的时候可以同时设置多个操作,比如设置CSS,设置innerHT ...
- 第一百三十九节,JavaScript,封装库--CSS选择器
JavaScript,封装库--修改元素选择器 就是将构造库函数修改成元素选择器,像css那样,输入#xxx .xxx xxx (获取指定id下的指定class下的指定标签元素) 修改后的基础库 / ...
- 第一百三十八节,JavaScript,封装库--插件
JavaScript,封装库--插件 库主要是用来封装一般JavaScript的常规操作代码,而拖拽这种特效代码属于功能性代码,并不是必须的,所以这种类型的代码,我们建议另外封装,在需要的时候作为插件 ...
- 第一百三十七节,JavaScript,封装库---修缮拖拽
JavaScript,封装库---修缮拖拽 修缮拖拽 /** tuo_zhuai()方法,将一个弹窗元素实现拖拽功能 * 注意:有参设置拖拽点区块,只有弹窗的这个拖拽点区块才能拖拽,无参整个弹窗可以拖 ...
- js实现第一次打开网页弹出指定窗口(常用功能封装很好用)
js实现第一次打开网页弹出指定窗口(常用功能封装很好用) 一.总结 1.常用功能封装:之前封装的cookie的操作函数非常好用,我自己也可以这么搞 二.js实现第一次打开网页弹出指定窗口 练习1:第一 ...
随机推荐
- 数据库Mysql的学习(二)-数据类型和创建
数据类型:数据列,存储过程参数,表达式和局部变量的数据特征. 整形: tinyint:一个字节,-128到127:2的7次方 smallint:两个字节,-32768到32767:2的15次方 med ...
- Python-3.6 安装pycrypto 2.6
最近接触公司后台管理系统的开发,其中涉及到加密模块pycrypto. 重点来了!!!!敲黑板!!!! pycrypto在PyCharm中跟其他的模块不一样,pip install pycrypto安装 ...
- 【RL系列】Multi-Armed Bandit笔记补充(一)
在此之前,请先阅读上一篇文章:[RL系列]Multi-Armed Bandit笔记 本篇的主题就如标题所示,只是上一篇文章的补充,主要关注两道来自于Reinforcement Learning: An ...
- Python3.5 Keras-Theano(含其他库)windows 安装环境
https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-4.2.0-Windows-x86.execonda --version ...
- C中文件操作的文本模式和二进制模式,到底有啥区别?
在C中,使用fopen打开文件有两种模式:一种是文本模式,一种是二进制模式.那这两种模式之间有什么区别,是不是使用文本模式打开的文件就只能使用文本函数比如fprintf来操作,而使用二进制打开的文件就 ...
- Alpha阶段中间产物
空天猎功能说明书:https://git.coding.net/liusx0303/Plane.git 空天猎代码控制:https://coding.net/u/MR__Chen/p/SkyHunte ...
- Thunder团队——事后诸葛亮会议
小组名称:Thunder 项目名称:爱阅APP 小组成员:王航 李传康 代秋彤 邹双黛 苗威 宋雨 胡佑蓉 杨梓瑞 一.设想和目标 1.我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型 ...
- Oracle ORA-12541:TNS:no listener错误解决方法 (转)
前天装好的Oracle,昨天突然不好用了,从Oracle的错误提示来看,是说TNS:no listener ,估计是某种服务没有启动,打开windows管理工具->服务,一看,有一个Oracle ...
- Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset Trie
题目链接: http://codeforces.com/contest/706/problem/D D. Vasiliy's Multiset time limit per test:4 second ...
- 3dContactPointAnnotationTool开发日志(三)
今天的目的是把obj文件导到场景里.具体将制定路径的obj文件导进去我用的是这个方法.导进去后呈现的是一个黑色的影子. 导入后还想实现一下缩放功能,请看这个方法.缩放实现起来也很简单. 光 ...