当前位置: 首页 > news >正文

原生html+js+jq+less 实现时间区间下拉弹窗选择器

 

html弹窗

  <div class="popupForm" id="popupForm10"><div class="pop-box"><i class="iconfont icon-quxiao cancel" onclick="toggleForm(10)"></i><div class="title">选择时间</div><div class="time-box"><div class="time"><!-- <span class="active">2025-7-28</span> --><span>开始时间</span>至<span>结束时间</span></div><div class="time-list flex-sb"><!-- 年 --><div class="year"><div class="li"></div><div class="li"></div><div class="li">2025年</div><div class="li">2024年</div><div class="li">2023年</div><div class="li">2022年</div><div class="li">2021年</div><div class="li">2020年</div><div class="li"></div><div class="li"></div></div><!-- 月 --><div class="month"><div class="li"></div><div class="li"></div><div class="li">1月</div><div class="li">2月</div><div class="li">3月</div><div class="li">4月</div><div class="li">5月</div><div class="li">6月</div><div class="li">7月</div><div class="li">8月</div><div class="li">9月</div><div class="li">10月</div><div class="li">11月</div><div class="li">12月</div><div class="li"></div><div class="li"></div></div><!-- 日 --><div class="day"><div class="li"></div><div class="li"></div><div class="li">1日</div><div class="li">2日</div><div class="li">3日</div><div class="li">4日</div><div class="li">5日</div><div class="li">6日</div><div class="li">7日</div><div class="li">8日</div><div class="li">9日</div><div class="li">10日</div><div class="li">11日</div><div class="li">12日</div><div class="li">13日</div><div class="li">14日</div><div class="li">15日</div><div class="li">16日</div><div class="li">17日</div><div class="li">18日</div><div class="li">19日</div><div class="li">20日</div><div class="li">21日</div><div class="li">22日</div><div class="li">23日</div><div class="li">24日</div><div class="li">25日</div><div class="li">26日</div><div class="li">27日</div><div class="li">28日</div><div class="li">29日</div><div class="li">30日</div><div class="li"></div><div class="li"></div></div></div><div class="bottom flex-cc"><button class="reset" onclick="resetTime()">重置</button><button class="confirm" onclick="confirmTime()">确定</button></div></div></div></div>

 less样式

.popupForm {display: none;width: 100%;height: 100%;position: fixed;bottom: 0;left: 0;background-color: #57575748;.pop-box {position: absolute;bottom: 0;left: 0;height: auto;width: 100%;border-radius: 0.625rem 0.625rem 0rem 0rem;background: #ffffff;padding: 1.25rem 0;}// 取消.cancel {font-size: 0.75rem;color: #606266;position: absolute;top: 1rem;right: 1.375rem;}.title {font-size: 1rem;color: #3d3d3d;text-align: center;}// 时间选择器.time-box {padding: 0.625rem 0;.time {font-size: 1rem;color: #606266;text-align: center;span {margin: 0 1.6875rem;padding: 0.1875rem 0.625rem;border-bottom: 0.0625rem solid #d8d8d8;font-size: 0.875rem;color: #909399;}.active {color: #1890ff;}}.time-list {height: 12.5rem;margin: 1.875rem 0;position: relative;box-shadow: inset 0 0.3125rem 0.625rem #d5d5d52e,inset 0 -0.3125rem 0.625rem #d5d5d52e;&::after {content: "";position: absolute;top: 5rem;left: 0;width: 100%;height: 0.0625rem;background-color: #eaeaea;}&::before {content: "";position: absolute;bottom: 5rem;left: 0;width: 100%;height: 0.0625rem;background-color: #eaeaea;}& > div {flex: 1;text-align: center;overflow-y: auto;&::-webkit-scrollbar {width: 0;height: 0;}.li {height: 2.5rem;font-size: 0.875rem;color: #606266;padding: 0.625rem 0;}}}.bottom {gap: 2.5rem;.reset {width: 7.875rem;height: 1.6875rem;border-radius: 2.125rem;border: 0.0625rem solid #c4302c;font-size: 0.875rem;color: #c4302c;}.confirm {width: 7.875rem;height: 1.6875rem;border-radius: 2.1875rem;background: linear-gradient(180deg, #eb140f 0%, #c70504 100%);font-size: 0.875rem;color: #ffffff;}}}
}

js整体逻辑 

$(() => {// 当前年份const thisYear = new Date().getFullYear();const ITEM_HEIGHT = 40; // 每个选项高度// 滚动类型:0=开始时间,1=结束时间let type = 0;let startTime = ""; //开始时间let endTime = ""; //结束时间// 存储滚动下标const scrollValues = {startYear: 0,startMonth: 1,startDay: 1,endYear: 0,endMonth: 1,endDay: 1,};// 缓存 DOM 元素const $year = $(".time-list .year");const $month = $(".time-list .month");const $day = $(".time-list .day");const $timeSpans = $(".time-box .time span");// ========== 生成年份列表(100年)==========function renderYearList() {let html = '<div class="li"></div><div class="li"></div>';for (let i = 0; i < 100; i++) {html += `<div class="li">${thisYear - i}年</div>`;}html += '<div class="li"></div><div class="li"></div>';$year.html(html);}// ========== 生成月份列表(1~12月)==========function renderMonthList() {let html = '<div class="li"></div><div class="li"></div>';for (let i = 1; i <= 12; i++) {html += `<div class="li">${i}月</div>`;}html += '<div class="li"></div><div class="li"></div>';$month.html(html);}// ========== 获取某年某月的天数(month: 1~12)==========function getDaysInMonth(year, month) {return new Date(year, month, 0).getDate();}// ========== 更新日列表(根据当前年月动态生成)==========function updateDayList() {const yearOffset =type === 0 ? scrollValues.startYear : scrollValues.endYear;const month = type === 0 ? scrollValues.startMonth : scrollValues.endMonth;const year = thisYear - yearOffset;const days = getDaysInMonth(year, month);const dayKey = type === 0 ? "startDay" : "endDay";const currentDay = scrollValues[dayKey];// 如果当前日超出该月最大天数,修正为最后一天if (currentDay > days) {scrollValues[dayKey] = days;}// 生成日 HTMLlet html = '<div class="li"></div><div class="li"></div>';for (let i = 1; i <= days; i++) {html += `<div class="li">${i}日</div>`;}html += '<div class="li"></div><div class="li"></div>';$day.html(html);// 滚动到当前日$day.scrollTop((scrollValues[dayKey] - 1) * ITEM_HEIGHT);}// ========== 格式化为 YYYY-MM-DD 字符串 ==========function formatTime(yearOffset, month, day) {const y = thisYear - yearOffset;const m = month < 10 ? `0${month}` : month;const d = day < 10 ? `0${day}` : day;return `${y}-${m}-${d}`;}// ========== 更新显示文本 ==========function updateDisplay() {const isStart = type === 0;const prefix = isStart ? "start" : "end";const year = scrollValues[prefix + "Year"];const month = scrollValues[prefix + "Month"];const day = scrollValues[prefix + "Day"];const formatted = formatTime(year, month, day);isStart ? (startTime = formatted) : (endTime = formatted); // 更新时间$timeSpans.eq(type).addClass("active").text(formatted);}// ========== 初始化滚动事件 ==========function initWheel() {[$year, $month, $day].forEach(($container) => {let isAnimating = false;$container.on("wheel", function (e) {e.preventDefault();if (isAnimating) return;const delta = e.originalEvent.deltaY > 0 ? 1 : -1;const current = $container.scrollTop();const maxScroll = this.scrollHeight - this.clientHeight;const nextScroll = Math.max(0,Math.min(maxScroll, current + delta * ITEM_HEIGHT));isAnimating = true;$container.animate({ scrollTop: nextScroll }, 200, () => {isAnimating = false;});// 计算滚动索引const index = Math.round(nextScroll / ITEM_HEIGHT);// 更新对应值if ($container.is($year)) {scrollValues[`${type === 0 ? "start" : "end"}Year`] = index;} else if ($container.is($month)) {scrollValues[`${type === 0 ? "start" : "end"}Month`] = index + 1;} else if ($container.is($day)) {scrollValues[`${type === 0 ? "start" : "end"}Day`] = index + 1;}updateDisplay(); // 更新显示updateDayList(); // 重新生成日(月或年变化时)});});}// ========== 切换时间类型(点击“开始/结束”)==========$timeSpans.parent().on("click", "span", function () {type = $(this).index();const values = [scrollValues[`${type === 0 ? "start" : "end"}Year`],scrollValues[`${type === 0 ? "start" : "end"}Month`] - 1,scrollValues[`${type === 0 ? "start" : "end"}Day`] - 1,];$year.scrollTop(values[0] * ITEM_HEIGHT);$month.scrollTop(values[1] * ITEM_HEIGHT);$day.scrollTop(values[2] * ITEM_HEIGHT);});// ========== 初始化 ==========$(function () {renderYearList();renderMonthList();updateDayList(); // 初始生成日initWheel();// 默认显示当前日期(可选)// $timeSpans.eq(0).text(formatTime(0, 1, 1));// $timeSpans.eq(1).text(formatTime(0, 1, 1));});// ========== 确认时间 ==========window.confirmTime = function () {// 判断开始结束时间是否正确console.log(startTime, endTime);if (startTime && endTime && startTime > endTime) {// message.error("结束时间不能小于开始时间");} else if (!startTime && endTime) {// message.error("请选择开始时间");} else if (startTime && !endTime) {// message.error("请选择结束时间");} else {// 关闭弹窗 请求接口toggleForm(10);}};// ========== 重置时间 ==========window.resetTime = function () {$(".time-box .time").html("<span>开始时间</span>至<span>结束时间</span>");Object.assign(scrollValues, {startYear: 0,startMonth: 1,startDay: 1,endYear: 0,endMonth: 1,endDay: 1,});$(".time-box .time span").eq(0).click(); // 触发切换并滚动};
});

打开关闭弹窗 

function toggleForm(type) {// console.log(type);$(`#popupForm${type}`).fadeToggle(200);
}

 

http://www.lryc.cn/news/603354.html

相关文章:

  • 鸿蒙网络编程系列59-仓颉版TLS回声服务器示例
  • 42、鸿蒙HarmonyOS Next开发:应用上下文Context
  • Apache Ignite 的分布式原子类型(Atomic Types)
  • 专业Python爬虫实战教程:逆向加密接口与验证码突破完整案例
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 微博文章数据可视化分析-文章评论量分析实现
  • Apache Ignite Cluster Groups的介绍
  • U3D中的package
  • 【PHP】Swoole:CentOS安装Composer+Hyperf
  • vue2 使用liveplayer加载视频
  • .NET Core 3.1 升级到 .NET 8
  • 自学嵌入式 day37 HTML
  • 前端代码格式化工具HTML离线版
  • LangChain学习笔记01---基本概念及使用
  • SkSurface---像素的容器:表面
  • echarts饼图
  • .NET测试平台Parasoft dotTEST在汽车电子行业的核心功能及应用
  • OpenAI Python API 完全指南:从入门到实战
  • 使用jQuery动态操作HTML和CSS
  • 从centos更换至ubuntu的安装、配置、操作记录
  • 系统选择菜单(ubuntu grub)介绍
  • 智能健康项链专利拆解:ECG 与 TBI 双模态监测的硬件架构与信号融合
  • Ubuntu22.04系统安装,Nvidia显卡驱动安装问题
  • 【Linux系统编程】Ext2文件系统
  • Java 9 新特性解析
  • VR全景制作流程分享-众趣VR全景制作平台
  • 博物馆 VR 导览:图形渲染算法+智能讲解技术算法实现及优化
  • 以需求破局:DPVR AI Glasses 重塑 AI 眼镜产业生态
  • 【OpenAI】ChatGPT辅助编码:Spring Boot + Copilot自动生成业务逻辑
  • Agent常用搜索引擎Tavily使用学习
  • VR 三维重建:开启沉浸式体验新时代