用闭包实作datePicker封装

前言
由于我在一开始很傻的自己刻了日曆,想说版面看起来很简单,但没有考虑到动态互动选择日期的功能,自以为这么简单,自己刻一刻就好,头都洗一半了,只好继续完成,花了一些时间把start date动态互动完成后,由于end date要做的事一模一样,不可能重新写一次,这样太傻了,我想一定可以共用程式码的吧!于是找啊找,恩...原来这叫封装,而且就是套件的原理来着,还好自己似乎没有太笨XD窃喜一下,但...知道要做什么却不见得做得出来,东试试西trytry,已经封到不知道哪去了,可能自己会先疯掉,瞥眼一见,馒头先生到了,用渴望的眼神向他求救,他竟然用闭包解决了我本来卡在constructor绕不出来的窘境,原来这么简单啊!好想跟他的脑交换一下XD

先介绍datePicker功能

起始画面,预设日期为当日http://img2.58codes.com/2024/20163234tLaw1BPSJe.pngcalender: 点击日期栏位会跳出Calendar,当日会反底色,其他日期hover后会反底色,标题栏位之左右方箭头可切换月份,标题"March 2024"按下后会跳出另一个可单独选择月份的monthPanel
http://img2.58codes.com/2024/201632342FGRnixzSt.pngmonthPanel:动态互动效果与calendar类似,中间标题"2024"按下后会跳出另一个可单独选择年份的yearPanel
http://img2.58codes.com/2024/20163234iEXFbVciPA.pngyearPanel:同理
http://img2.58codes.com/2024/20163234GCWZqNYGKF.png使用者点击自己欲指定年份,会跳回monthPanel,指定月份后跳回calendar,指定日期后,calendar消失,选取完起始画面的日期必须跟着变动

实作步骤

首先把html跟javascript的程式码并排对照整理程式码,单纯函式不影响,其他程式码就要考虑放的位置是否合适,例如:原本calendar,monthPanel跟yearPanel里与起始画面日期连动的程式码如下,我写在init()之外,其实照理说应该在包在init()中。菜菜如我傻傻不自知,馒头先生就帮我把它整理进去
        let dayElement = document.querySelector(`${targetSelector} #dayElement`);        dayElement.addEventListener("click", function(event) {            if (event.target.className.includes("visible_date")) {                datePicked.setDate(event.target.textContent);                datePicked.setMonth(state.current.getMonth());                datePicked.setYear(state.current.getFullYear());                showDatePicked(datePicked, datePicker);                render();            }        });        let monthElement = document.querySelector(`${targetSelector} #monthElement`);        monthElement.addEventListener("click", function(event) {            if (event.target.className.includes("visible_month")) {                let monthOrder = monthAbbreviation.indexOf(event.target.textContent);                datePicked.setMonth(monthOrder);                datePicked.setYear(state.current.getFullYear());                showDatePicked(datePicked, datePicker);                monthChange(monthOrder);                render();            }        });        let yearElement = document.querySelector(`${targetSelector} #yearElement`);        yearElement.addEventListener("click", function(event) {            if (event.target.className.includes("visible_year")) {                datePicked.setYear(event.target.textContent);                showDatePicked(datePicked, datePicker);                yearChange(event.target.textContent);                render();            }        });
确认封装範围,剪下HTML程式码创造函式renderHTML(element)刚才剪下的整串程式码即为renderHTML函式内容
        function renderHTML(element){            element.innerHTML = `...刚刚剪下的程式码`        }
再来加上下面程式码:
        const datePickerWrapper = document.querySelector('#datePickerFrom');        renderHTML(datePickerWrapper);
由于datePickerFrom是给start date用的,所以要改成变数,之后才可以再创一个datePickerTo给end date用,于是闭包就登场啦!登登登登登
        function componentDatePicker(targetSelector) {            function renderHTML (element) {            element.innerHTML = `......`            }            const datePickerWrapper = document.querySelector(targetSelector);            renderHTML(datePickerWrapper);        }
再来就是呼叫
        componentDatePicker("#datePickerFrom");        componentDatePicker("#datePickerTo");
基本上静态的html到此就已经ok了,之后再原封不动的把已完成的javascript程式码也搬到componentDatePicker内容接续在底下,该跟着加上targetSelector的地方记得加上就大功告成啰!举例:原本只有写#previousMonth,前面要加上${targetSelector}才能找到在targetSelector底下的dom element
    const previousMonth = document.querySelector(`${targetSelector} #previousMonth`)    previousMonth.addEventListener('click', function() {    state.current.setMonth(state.current.getMonth() - 1);    render();    })

大致实作步骤就介绍到这里,讲个概念,也许有需要的人应该能有一点灵感,整包太繁杂就不放了。封装完成后,成就感满满ㄚ!太感动了

参考资料

可敬的馒头先生脑XD

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章