原文请关注公众号 ”酒酒酒酒“​,关注公众号 回复  ”JS 通过年份获取月,季度,半年度,年度“ 可获取源代码

功能描述:

实例化一个函数,给函数内传递不同的参数,获取从起始年份到现在年度所有的月份,季度,半年度,年度

动态演示

---------正文代码开始--------

1. 封装函数 createMonth 注:此代码可直接复制黏贴使用

function createMonth() {

  let typeText = "";
let today = new Date();
// 获取当前的年
let currentYear = today.getFullYear();
// 获取当前的月份
let currentMonth = today.getMonth() + 1;
// 输出数据
this.arr = [];
this.type = "";
this.year = "";
this.currentMonth = currentMonth;
this.currentYear = currentYear; /*
@desc 初始化函数,页面进来先调用init函数,实例化createMonth函数后, 调用init函数回将生成的数据 return 出去,每次生成新的数据
@param {数字} year 接收字符串类型的4位数字年份
@param {数字} type 1 月度,2 季度,3 半年度,4 年度
@param {布尔} isCurrentMonth 是否展示当前的月份,季度,半年度,年度
isCurrentMonth=false 不展示
isCurrentMonth=true 展示
@param {布尔} isSort 是否升序 true 升序[从小往大排序] false 降序[从大往大排序]
@param {数字} sortType 排序规则 1 以月进行排序, 4 以年进行排序
*/
this.init = function(year, type, isCurrentMonth = false, isSort = false,sortType=4) {
this.type = type;
this.year = year;
this.isCurrentMonth = isCurrentMonth;
this.arr = [];
this.setYear();
this.setType();
let copyArr=JSON.parse(JSON.stringify(this.arr));
let labelKey='year';
// let label=sortType==1?'val':'year';
if(sortType==1){
labelKey='val';
}else{
labelKey='year';
}
this.arr=copyArr.sort(this.dateDataSort(labelKey,isSort))
return this.arr;
}
// 处理接受到的type值
/*
处理接受到type类型,如果没有值,就赋默认值月即1
*/
this.setType = function() {
// type 不存在就赋默认值为4
let type = this.type || 4;
if (type == 1) {
// 月度
typeText = '月';
this.setMonthData();
} else if (type == 2) {
// 季度
typeText = '季度';
this.setQuarterData();
} else if (type == 3) {
// 半年度
typeText = '半年度';
this.setSemiannualData();
} else if (type == 4) {
// 年度
typeText = '年度';
this.setYearListData();
}
}
// 处理接受到的年份
/*
处理接受到的年份,如果没有值就赋默认值为当前的年
*/
this.setYear = function() {
let year = this.year;
// 判断接收到的年份是否是数值类型
if (year && Object.prototype.toString.call(year) != "[object Number]") {
year = Number(year);
} else if (!year) {
year = currentYear;
}
this.year = year;
} // 去重 数组对象去重
this.removeDuplicateObjects = function(array, label) {
const obj = {};
let arr = [];
label = label || 'label';
arr = array.reduce((total, next) => {
let key = next[label]
if (key) {
obj[key] ? '' : obj[key] = true && total.push(next)
return total
}
}, []);
return arr;
}
// 排序 数组属性值相同的排列到一起
this.setArrSort = function(dataArr, keys) {
dataArr = JSON.parse(JSON.stringify(dataArr));
keys = keys || 'year'
return dataArr.sort((a, b) => {
if ((a[keys].toString()) != (b[keys].toString())) {
return (a[keys].toString()).localeCompare(b[keys].toString());
}
})
}
// 升降序函数
/*
property是你需要排序传入的key,bol为true时是升序,false为降序
bol 是否升序 true 升序 false 降序
*/
this.dateDataSort=function(property, bol) {
return function(a, b) {
var value1 = a[property];
var value2 = b[property];
if (bol) {
// 升序
return Date.parse(value1) - Date.parse(value2);
} else {
// 降序
return Date.parse(value2) - Date.parse(value1)
}
}
}
// 是否过滤掉当前年的当前月,季度,年度,以及当前年的下半年
// 设置年度
this.setYearListData = function() {
// console.log('设置年度');
// 设置当前年的年数据
if (this.year == currentYear) {
let obj = {
year: this.year,
val: 1,
type: this.type,
typeText: '年度',
label: this.year + '年'
}
this.arr.push(obj);
} else if (this.year < currentYear) {
// 设置小于当前年的年数据
for (let i = this.year; i <= currentYear; i++) {
let obj = {
year: i,
val: 1,
type: this.type,
typeText: '年度',
label: i + '年'
}
this.arr.push(obj);
} // 是否展示当前的年
//
if (this.isCurrentMonth == false && this.type == 4) {
this.arr.forEach((item, index, arr) => {
// 过滤掉当前的年
if (item.year == currentYear) {
this.arr.splice(index, 1);
}
}); }
}
}
// 设置半年度
// 此处调用的年度来生成半年度
this.setSemiannualData = function() {
// console.log('设置半年度');
// 调用年数据,用以生成上半年和下半年
this.setYearListData();
// 此处用了深拷贝,如若不使用深拷贝,copyArr最后的数据无法改变
let copyArr = JSON.parse(JSON.stringify(this.arr));
// 因为是上半年,下半年,所以使用了数据拼接,将原有数据再次拼接一次
copyArr = copyArr.concat(this.arr);
// 数据排序,将相同年份的数据放到一起
let sortArr = this.setArrSort(copyArr);
// 需要删除下标
let deleteIndex = null;
// 数据排序后重新赋值
copyArr = sortArr;
// 用以标注上半年,下半年;1上半年,2下半年
let val = 1;
let label = "上半年"
for (let i = 0; i < copyArr.length; i++) {
// 当前月份大于6就是上半年
if (currentMonth > 6 && (i % 2 == 0)) {
val = 1;
// 当前月份在6-12就是下半年
} else if (currentMonth > 6 && currentMonth < 12 && (i % 2 != 0)) {
val = 2;
} label = val == 1 ? '上半年' : '下半年';
copyArr[i].val = val;
copyArr[i].typeText = label;
copyArr[i].label = copyArr[i].year + '年' + label;
// 获取当前年的下半年下标
if (copyArr[i].year == currentYear && copyArr[i].val == 2) {
deleteIndex = i;
}
}
// 是否过展示当前年度下半年
if (this.isCurrentMonth == false) {
// 移除当前年的下半年
copyArr.splice(deleteIndex, 1);
}
this.arr = copyArr; }
// 设置季度
// setQuarterData函数是通过月度来生成季度的
this.setQuarterData = function() {
// console.log('设置季度');
// 调用月度
this.setMonthData();
let arr = [];
let copyArr = JSON.parse(JSON.stringify(this.arr));
copyArr = copyArr.map((item, i, arr) => {
// 使用月份除以3向上取整,获取到是第几季度
let val = Math.ceil(item.val / 3);
item.val = val;
item.label = item.year + '年' + item.val + '季度'
return item;
});
// 因为调用了生成的月份,因此要过滤掉相同的数据
arr = this.removeDuplicateObjects(copyArr, 'label');
this.arr = arr;
}
// 设置月度
this.setMonthData = function() {
// console.log('设置月度');
// 调用年度
this.setYearListData();
let arr = [];
let copyArr = JSON.parse(JSON.stringify(this.arr));
// 最大月份
let maxMonth = currentMonth;
// 需要删除的数据下标
let deleteIndex = null;
for (let i = 0; i < copyArr.length; i++) {
// 如果年份小于当前的年,最大月份赋值12,如果如果年份等于当前的年,最大月份就是当前月份
if (copyArr[i].year < currentYear) {
maxMonth = 12;
} else if (copyArr[i].year == currentYear) {
maxMonth = currentMonth;
}
for (let m = 1; m <= maxMonth; m++) {
let obj = {
year: copyArr[i].year,
val: m,
type: this.type,
typeText: typeText,
label: copyArr[i].year + '年' + m + '月'
}
/*
过滤当前月份
获取当前月份的下标, 用于删除当前的月份
考虑到性能问题 所以注释掉了
*/
// if (copyArr[i].year == currentYear && m==currentMonth) {
// deleteIndex=m;
// }
arr.push(obj);
}
}
// 是否展示当前月份
if (this.isCurrentMonth == false) {
// arr.splice(deleteIndex,1)
arr = arr.filter(function(item) {
if (item.year == currentYear) {
// 移除当前的月
return item.val !== currentMonth;
} else {
return item;
}
});
}
this.arr = arr;
} }

2. 函数解释说明

使用一下函数之前,需要先实例化createMonth函数为对象,具体看以下步骤三

2.1. this.init  初始化函数

2.11.   createMonth 实例化完成后,需要调用此函数来调用实例化函数内部其他数,给一些关键性数据赋值,并且回把生成好的数据return出去

2.12. init  函数接收三个参数  year,type,isCurrentMonth

year: 接收字符串类型的4位数字年份

type: 1 月度,2 季度,3 半年度,4 年度

isCurrentMonth:true/false 是否展示当前的月份,季度,半年度,年度

isCurrentMonth:true 展示

isCurrentMonth:false 不展示,默认是false

当值是 false  时,使用了JS的 splice  移除了当前年,月,季度,和当前年的下半年

2.2 this.setType    处理接受到的type值,类型为数值类型

处理接受到type类型,如果没有值,就赋默认值月即1

2.3 this.setYear

处理接受到的年份,如果没有值就赋默认值为当前的年

2.4 this.removeDuplicateObjects

2.4.1. 去重 数组对象去重,在网找的方法,自己做了稍加修改

接收两个参数:array,label

array 数组对象

label 对象中过滤的key名称

2.5 this.setArrSort 排序  数组属性值相同的排列到一起

2.6 this.setYearListData  生成年数据

在生成半年度,月度数据时候,也调用了setYearListData 该函数

2.7 this.setSemiannualData    生成半年度数据

该函数里面调用了年函数setYearListData,使用深拷贝,生成了双份数据

2.8 this.setQuarterData  生成季度数据

该函数里面调用了月函数setMonthData来生成季度,通过月份除以三向上取整,获取到是第几季度

因为调用了月份函数setMonthData,导致生成的季度产生了重复数据,就是用了 removeDuplicateObjects 函数去重

2.9 this.setMonthData  生成月度数据

该函数里面调用了年函数setYearListData,用于生成对应年的月份

3. 函数调用-通过控制台查看

// 实例化 createMonth 函数 为一个对象
var start = new createMonth();
console.log("打印实例:",start);
// 调用实例化函数中的init函数传参,false 不展示当前月,季度,半年度,年
let arr1=start.init('2023', '1' ,false);
// 调用实例化函数中的init函数传参,true 展示当前月,季度,半年度,年
let arr2=start.init('2023', '1' ,true);
console.log("原始arr",start.arr);
console.log('arr1:',arr1);
console.log('arr2:',arr2);

--------正文代码结束--------

4. 函数调用-通过UI页面查看,如果上面正文已经理解,可以忽略以下UI页面演示

4.1 演出页面引用了layui,演示代码可以直接使用

4.2  引入layui依赖

<!-- 引入 layui.css -->
<link rel="stylesheet" href="https://unpkg.com/layui@2.6.8/dist/css/layui.css"> <!-- 引入 layui.js -->
<script src="https://unpkg.com/layui@2.6.8/dist/layui.js"></script>

4.2 演示使用的 HTML代码

<formclass="layui-form layui-form-pane"action="">

  <div class="layui-form-item" pane>    <label class="layui-form-label">选择年份</label>    <div class="layui-input-inline">      <input type="text" class="layui-input" id="test1">    </div>  </div>  <div class="layui-form-item">    <label class="layui-form-label">选择类别</label>    <div class="layui-input-block">      <input type="radio" name="type" value="1" title="月度" lay-filter="demo-radio">      <input type="radio" name="type" value="2" title="季度" lay-filter="demo-radio">      <input type="radio" name="type" value="3" title="半年度" lay-filter="demo-radio">      <input type="radio" name="type" value="4" title="年度" lay-filter="demo-radio" checked>    </div>  </div>  <div class="layui-form-item" pane>    <label class="layui-form-label">是否开启</label>    <div class="layui-input-block">      <input type="checkbox" value="false" lay-skin="switch" lay-filter="demo-checkbox-switch" lay-text="开启|关闭">      <div class="layui-bg-orange">是否展示现在年的当前月份,现在年的当前季度,现在年的下半年度,现在的年度</div>    </div>  </div>  <div class="layui-form-item" pane>    <label class="layui-form-label">升序/降序</label>    <div class="layui-input-block">      <input type="checkbox" value="false" lay-skin="switch" lay-filter="demo-issort" lay-text="升序|降序">    </div>  </div>  <div class="layui-form-item" pane>    <label class="layui-form-label">排序规则</label>    <div class="layui-input-block">      <input type="radio" name="sortType" value="1" title="月度" lay-filter="demo-sort-typel">      <input type="radio" name="sortType" value="4" title="年度" lay-filter="demo-sort-typel" checked>      <div class="layui-bg-orange">以月度排序:年度保持不变,按月度,季度,半年度排序</div>      <div class="layui-bg-orange">以年度排序:月度,季度,半年度保持不变,按年度排序</div>      <div class="layui-bg-orange">注意:选择类别是年度,排序规则是月度的时候,升序/降序排序将不会起作用</div>    </div>  </div></form><!-- 展示数据到页面上 --><table id="tableDemo" lay-filter="tableDemo"></table>

4.3 演示使用的相关JS代码

var start = new createMonth();

let selectYear = "",  selectType = 4,  isCurrentMonth = false,  isSort = true,  sortType=4;let dataArr = [];dataArr = start.init(selectYear, selectType, isCurrentMonth, isSort,sortType);createTable();layui.use(['laydate', 'form', 'table'], function() {  var laydate = layui.laydate;  var form = layui.form;  var table = layui.table;  var tableReload = table.reload;  var $ = layui.$;  // 日期触发函数  laydate.render({    elem: '#test1', //指定元素    type: 'year',    format: 'yyyy', //可任意组合    done: function(value, date, endDate) {      //得到日期生成的值,如:2017-08-18      // console.log(value);      selectYear = value;      dataArr = start.init(selectYear, selectType, isCurrentMonth);      // console.log(dataArr);      createTable();      //得到日期时间对象:{year: 2017, month: 8, date: 18, hours: 0, minutes: 0, seconds: 0}      // console.log(date);    }  });  // 监听单选框-选择类别  form.on('radio(demo-radio)', function(data) {    // console.log(data.elem); //得到radio原始DOM对象    // console.log(data.value); //被点击的radio的value值    selectType = data.value;    dataArr = start.init(selectYear, selectType, isCurrentMonth, isSort,sortType);    console.log(dataArr);    createTable();  });  // 监听开关-是否开启  form.on('switch(demo-checkbox-switch)', function(data) {    // console.log(data.elem); //得到checkbox原始DOM对象    // console.log(data.elem.checked); //开关是否开启,true或者false    isCurrentMonth = data.elem.checked;    dataArr = start.init(selectYear, selectType, isCurrentMonth, isSort,sortType);    console.log(dataArr);    createTable();    // console.log(data.value); //开关value值,也可以通过data.elem.value得到    // console.log(data.othis); //得到美化后的DOM对象  });  form.on('switch(demo-issort)', function(data) {    // console.log(data.elem); //得到checkbox原始DOM对象    // console.log(data.elem.checked); //开关是否开启,true或者false    isSort = data.elem.checked;    dataArr = start.init(selectYear, selectType, isCurrentMonth, isSort,sortType);    console.log(dataArr);    createTable();    // console.log(data.value); //开关value值,也可以通过data.elem.value得到    // console.log(data.othis); //得到美化后的DOM对象  });  form.on('radio(demo-sort-typel)', function(data) {    // console.log(data.elem); //得到checkbox原始DOM对象    sortType = data.value;    dataArr = start.init(selectYear, selectType, isCurrentMonth, isSort,sortType);    console.log(dataArr);    createTable();    // console.log(data.value); //开关value值,也可以通过data.elem.value得到    // console.log(data.othis); //得到美化后的DOM对象  });});
function createTable() { layui.use('table', function() { var table = layui.table; table.render({ elem: '#tableDemo', id: "demoReload", height: 600, page: true, limit: 12, data: dataArr, parseData: function(res) { //res 即为原始返回的数据 console.log(res); }, cols: [ [ //表头 { field: 'label', title: '名称', sort: true, fixed: 'left' }, { field: 'year', title: '年份', sort: true }, { field: 'typeText', title: '类型' }, { field: 'val', title: 'val值' }, { field: 'type', title: 'type值' } ] ] }) })}

JS 通过年份获取月,季度,半年度,年度的更多相关文章

  1. js根据年份获取某月份有几天

    function getNum(year, month) { var temp; month = parseInt(month, 10); temp = new Date(year, month, 0 ...

  2. js简单日期获取( 菜鸟入门基础)

    关于js日期的获取要用到最基本的Date()方法获取当日的日期 var d =new Date();  //定义日期对象 var y=d.getFullYear();   //获取年 var m=d. ...

  3. js 根据身份证获取出生日期及性别

      js根据身份证获取出生日期及性别 CreateTime--2017年6月2日11:45:16Author:Marydon 第一步:身份证号格式校验 /** * 身份证号格式校验 */ functi ...

  4. 整理 js 日期对象的详细功能,使用 js 日期对象获取具体日期、昨天、今天、明天、每月天数、时间戳等,以及常用的日期时间处理方法

    在 javascript 中内置了一个 Date 对象,可用于实现一些日期和时间的操作. 本文整理 js 日期对象的详细功能,使用 js 日期对象获取具体日期.昨天.今天.明天.每月天数.时间戳等,以 ...

  5. js设置、获取单值cookie和多值cookie

    js设置.获取单值cookie和多值cookie,代码如下: var CookieUtil = (function () { var Cookie = function () { // 获取单值coo ...

  6. js之如何获取css样式

    js之如何获取css样式   一.获取内联样式 1 <div id ="myDiv" style="width:100px;height:100px; border ...

  7. offsetWidth、clientWidth、width、scrollWidth区别及js与jQuery获取的方式

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. js 和 jquery 获取页面和滚动条的高度 视口高度文档高度

    js 和 jquery 获取页面和滚动条的高度 //页面位置及窗口大小 function GetPageSize() { var scrW, scrH; if(window.innerHeight & ...

  9. js与jquery获取父元素,删除子元素的不同方法

    var obj=document.getElementById("id");得到的是dom对象,对该对象进行操作的时候使用js方法 var obj=$("#id" ...

  10. 2.Node.js access_token的获取、存储及更新

    文章目录:         1.Node.js 接入微信公众平台开发         2.Node.js access_token的获取.存储及更新 一.写在前面的话   上一篇文章中,我们使用 No ...

随机推荐

  1. java多线程之-CAS无锁

    1.背景 加锁确实能解决线程并发的的问题,但是会造成线程阻塞等待等问题 那么有没有一种方法,既可以线程安全,又不会造成线程阻塞呢? 答案是肯定的......请看如下案例 注意:重要的文字说明,写在了代 ...

  2. mysql数据库主从同步读写分离(二)读写分离实现

    步骤: a.解压文件 b.添加如下配置文件 c.mysql-proxy.conf配置内容如下: 1 [mysql-proxy] 2 admin-username=proxy 3 admin-passw ...

  3. dubbo服务治理(一)降级

    在线网站一般都会有服务器压力剧增的时候,比如说网上商城的促销,这个时候常用的手段就是服务降级,根据当前业务情况及流量对一些服务和页面有策略的降级,以此缓解了服务器资源压力,以保证核心任务的正常运行,同 ...

  4. 【防忘笔记】Spring+Struts2古董框架学习

    Spring+Struts2项目框架梳理 若基于Spring+Struts2的方式进行开发,前后端的交互逻辑会与boot系以及MCV的组织结构有所不同 这里是对于学习过程的一些记录 前置通用知识 St ...

  5. C#学习日记

    2023年9月9日 工具visual stdio 2019 窗口名称修改 lable标签 button 点击事件 点击换颜色 formLearn.ActiveForm.BackColor = Colo ...

  6. 【Docker学习系列】Docker学习2-docker设置阿里云镜像加速器

    在上一篇中,我们学会了在centos中安装docer.我们知道,镜像都是外网的,镜像一般都是比较大的,因为种种原因,我们知道,从外网下载比较慢的.所以,本文,凯哥就介绍怎么将docker的镜像拉取设置 ...

  7. python将资源打包进exe

    前言 之前py打包的exe一直是不涉及图片等资源的,直到我引入图片后打包,再双击exe发现直接提示未找到资源. 分析 我py代码中的图片引入使用的是项目相对路径,打包时pyinstaller只会引入p ...

  8. 8.30域横向-PTH&PTK&PTT票据传递

    知识点 Kerberos协议具体工作方法,在域中: 客户机将明文密码进行NTLM哈希,然后和时间戳一起加密(使用krbtgt密码hash作为密钥),发送给kdc(域控),kdc对用户进行检测,成功之后 ...

  9. Docker镜像源地址

    Docker镜像源地址(1)官方镜像:https://registry.docker-cn.com(2)网易镜像:http://hub-mirror.c.163.com(3)清华大学:https:// ...

  10. 【题目全解】ACGO排位赛#12

    ACGO 排位赛#12 - 题目解析 别问为什么没有挑战赛#11,因为挑战赛#11被贪心的 Yuilice 吃掉了(不是). 本次挑战赛难度相比较前面几次有所提升. 爆料:小鱼现在已经入职了研发部门, ...