亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

帶你輕松搞定時(shí)間選擇控件原理

tigerZH / 2836人閱讀

摘要:雖然大家都用過(guò)這個(gè)時(shí)間選擇控件,但是卻很少有人去研究其中原理。最近這邊本人利用閑暇時(shí)間自己寫了一個(gè)時(shí)間選擇控件,借這個(gè)時(shí)間選擇控件向各位同學(xué)們闡述這個(gè)時(shí)間選擇控件的原理。

前言

??說(shuō)到這個(gè)時(shí)間選擇控件,網(wǎng)上有很多各式各樣的,相信很多同學(xué)們也都有用過(guò),所以大家對(duì)這個(gè)也不陌生。雖然大家都用過(guò)這個(gè)時(shí)間選擇控件,但是卻很少有人去研究其中原理。最近這邊本人利用閑暇時(shí)間自己寫了一個(gè)時(shí)間選擇控件,借這個(gè)時(shí)間選擇控件向各位同學(xué)們闡述這個(gè)時(shí)間選擇控件的原理。我向大家演示肯定是比較簡(jiǎn)單,相對(duì)來(lái)說(shuō)更容易理解一點(diǎn)。但是呢,考慮到實(shí)用性,我就把這個(gè)時(shí)間選擇控件改進(jìn)了一下,讓其變成了一個(gè)移動(dòng)端時(shí)間選擇控件,希望同學(xué)們?nèi)绻矚g我這邊文章的話,麻煩幫個(gè)點(diǎn)個(gè)贊哦!不勝感謝!

項(xiàng)目演示 本文項(xiàng)目地址

https://github.com/ruichengpi...

本文演示地址

https://ruichengping.github.i...

本文演示效果圖

--------------------------------分割線----------------------------------

完整項(xiàng)目地址(移動(dòng)端) github地址

https://github.com/ruichengpi...

演示地址

https://ruichengping.github.i...

理一下思路

??基于上面的效果演示圖,我們第一件事就是理清思路。很多同學(xué)呢,一開(kāi)始如果做這個(gè)東西可能一頭霧水,都不知道從哪里開(kāi)始入手。這里我就大家理一下。

??對(duì)這種插件的開(kāi)發(fā),我個(gè)人建議先不要急著考慮其封裝之類的情況,我們就從最簡(jiǎn)單的開(kāi)始入手。那什么是最簡(jiǎn)單的呢?那肯定就是html+css+js的模式最簡(jiǎn)單的。什么意思呢?我這里解釋一下,現(xiàn)在就是單純做一個(gè)效果,html控制骨架,css美化樣式,js實(shí)現(xiàn)交互,不要考慮復(fù)用性。

??既然我們選擇html+css+js先去實(shí)現(xiàn)效果,那么著手開(kāi)始先把時(shí)間選擇控件的html的dom結(jié)構(gòu)寫出來(lái),然后用css去調(diào)整其中的樣式。html和css的內(nèi)容很簡(jiǎn)單,這里我就不把代碼貼出來(lái),同學(xué)們看完這篇文章可以去我的github項(xiàng)目下中Jcalendarlearn文件夾查看。下面我們說(shuō)一下交互有哪些東西。

JS交互實(shí)現(xiàn)

??關(guān)于這個(gè)JS交互,我們首先要弄清楚這個(gè)時(shí)間選擇控件有哪些交互。我先列舉一下:

年份、月份的增加減少按鈕

根據(jù)input框的位置,設(shè)置時(shí)間選擇器的位置

根據(jù)年份、月份獲取對(duì)應(yīng)的日期數(shù)據(jù)

日期的選擇

時(shí)間選擇器顯示隱藏

下面一一這些功能。

根據(jù)年份、月份獲取對(duì)應(yīng)的日期數(shù)據(jù)

??我們先來(lái)闡述這個(gè)功能是如何實(shí)現(xiàn),這是整個(gè)時(shí)間選擇控件的基石,弄清楚這個(gè),后面的問(wèn)題都會(huì)變得簡(jiǎn)單。初看到這個(gè)確實(shí)很難,一頭霧水,都不知道如何下手。遇到這種問(wèn)題的時(shí)候,先不要考慮如何去實(shí)現(xiàn),首先我們弄清楚這個(gè)日期數(shù)據(jù)是由那幾塊組成。我認(rèn)真地想想,發(fā)現(xiàn)每一組日期數(shù)據(jù)都有這樣一個(gè)等式。

日期數(shù)據(jù)=上一月的日期+這個(gè)月的日期+下個(gè)月的日期

那為什么會(huì)這么組成呢?可能有同學(xué)們有這樣子的疑問(wèn),不急不急,聽(tīng)我接下來(lái)解釋一下。

一個(gè)星期是有七天,我們最長(zhǎng)的一個(gè)月是31天,就是4個(gè)星期余三天。如果每一行代表星期,那么五行就可以搞定了。但是看效果演示圖我們可以看出來(lái),我們用了6行。為什么會(huì)多一行?這個(gè)問(wèn)題很好解釋,并不是每一個(gè)月的第一天都是從星期天開(kāi)始的,所以我們要考慮最壞的情況。如果從星期六開(kāi)始,此時(shí)需要6+31=37格(換上一下,就是5行多2格)。為了滿足這種最壞的情況,我們就需要6行了。

通過(guò)上面解釋,我們可以發(fā)現(xiàn)有一個(gè)特例并不滿足這個(gè)等式。那就是這個(gè)月第一天是從星期天開(kāi)始的。不過(guò)這個(gè)特例并不影響我們用這種思路去思考問(wèn)題,所以我們可以不管這個(gè)特例。下面我就看一下,這每一塊數(shù)據(jù)是如何得到的。

上個(gè)月

關(guān)于得出這塊數(shù)據(jù),我們先不要考慮其具體組成。首先考慮的是個(gè)數(shù),需要幾個(gè)我們給它弄幾個(gè)。怎么知道需要多少個(gè)呢?很簡(jiǎn)單,弄清楚這個(gè)月的第一天是星期幾就可以了。

/**
 *獲取currentYear年currentMonth月的第一天是星期幾
 *month參數(shù)是要比實(shí)際上少一天的
 *0 代表星期天 6代表星期六
 **/
new Date(currentYear,currentMonth-1,1).getDay();

當(dāng)我得出需要幾個(gè)上一月日期數(shù)據(jù)之后,我們還需要一樣?xùn)|西。那就是上一個(gè)月的最后一天,根據(jù)這個(gè)來(lái)往前推。

/**
 *獲取currentYear年currentMonth月的最后一天的日期
 *month參數(shù)是要比實(shí)際上少一天的
 **/
new Date(currentYear,currentMonth-1,0).getDate();
這個(gè)月

這個(gè)月的日期數(shù)據(jù)相比較上一個(gè)就簡(jiǎn)單多了,只需要知道這一月的第一天和最后一天即可。

//獲取currentYear年currentMonth月的第一天的日期
new Date(currentYear,currentMonth-1,1).getDate();
//獲取currentYear年currentMonth月的最后一天的日期
new Date(currentYear,currentMonth,0).getDate();
下一月

這塊數(shù)據(jù)也非常簡(jiǎn)單,總共7*6=42格,剩下幾格就往里面填幾個(gè)。我們這里只需要知道下一個(gè)月的第一天是多少就行了。

//獲取currentYear年currentMonth月的下一月的一天的日期
new Date(currentYear,currentMonth,1).getDate();
最終的JS代碼
    //根據(jù)年,月獲取日數(shù)組
    function getMonthData(year, month, day) {
        var days = [];
        var today = new Date();
        if (!year | !month | !day) {
            year = today.getFullYear();
            month = today.getMonth() + 1;
            day = today.getDate();
        }
        //獲取該月第一天的Date對(duì)象
        var firstDateObj = new Date(year, month - 1, 1);
        //獲取該月第一天對(duì)應(yīng)的星期幾
        var firstDateWeekDay = firstDateObj.getDay();
        //獲取該月最后一天的Date對(duì)象
        var lastDateObj = new Date(year, month, 0);
        //獲取該月最后一天的日期
        var lastDate = lastDateObj.getDate();
        //獲取上一個(gè)月最后一天的Date對(duì)象
        var lastDateOfPrevMonthObj = new Date(year, month - 1, 0);
        //獲取上一個(gè)月最后一天的日期
        var lastDateOfPrevMonth = lastDateOfPrevMonthObj.getDate();
        //上月
        for (var i = 0; i < firstDateWeekDay; i++) {
            var className = "available disabled";
            var thisMonth = month - 1;
            var date = lastDateOfPrevMonth - firstDateWeekDay + i + 1;
            if (thisMonth === 0) {
                thisMonth = 1;
            }
            days.push({
                "date": date,
                "showDate": date,
                "thisMonth": thisMonth,
                "className": className
            });
        }
        //本月
        for (var i = 0; i < lastDate; i++) {
            var className = "available";
            var date = i + 1;
            var thisMonth = month;
            if (date === day) {
                className = "available current";
            }
            if (today.getDate() === date && today.getFullYear() === year && today.getMonth() + 1 === month) {
                days.push({
                    "date": date,
                    "showDate": "今天",
                    "thisMonth": thisMonth,
                    "className": className
                });
            } else {
                days.push({
                    "date": date,
                    "showDate": date,
                    "thisMonth": thisMonth,
                    "className": className
                });
            }

        }
        var nextMonthLength = days.length;
        //下月
        for (var i = 0; i < 7 * 6 - nextMonthLength; i++) {
            var className = "available disabled";
            var date = i + 1;
            var thisMonth = month + 1;
            if (thisMonth === 13) {
                thisMonth = 12;
            }
            days.push({
                "date": date,
                "showDate": date,
                "thisMonth": thisMonth,
                "className": className
            });
        }
        return {
            "year": firstDateObj.getFullYear(),
            "month": firstDateObj.getMonth() + 1,
            "days": days
        }
    }
年份、月份的增加減少按鈕

??這塊沒(méi)有難的點(diǎn),需要注意的就是臨界值得判斷。比如說(shuō)12月再加1個(gè)月,不能變成13月,而是年份加1,月份置為1.

根據(jù)input框的位置,設(shè)置時(shí)間選擇器的位置

??這塊內(nèi)容也很簡(jiǎn)單,弄清楚left值和top值是如何計(jì)算的即可。

top值=input輸入框到瀏覽器窗口頂部的距離+input自身的高度
left值=input輸入框到瀏覽器窗口左邊的距離

??上面需要注意的是距離游覽器而不是整個(gè)文檔,因?yàn)槲覀冇玫膄ixed而不是absolute。

日期的選擇

??這里沒(méi)有難點(diǎn),但是有一個(gè)新手非常容易犯錯(cuò)的錯(cuò)誤。在為日期綁定事件的時(shí)候,新手很容易就會(huì)找到當(dāng)前頁(yè)面所有日期給它綁定事件。這樣顯然是行不通的,因?yàn)槿掌跀?shù)據(jù)是不斷變得,也就是日期這些dom元素是會(huì)替換了的,之前綁定的事件也就不見(jiàn)了,所以我建議大家用事件委托機(jī)制??赡軙?huì)有人反駁我,每一天改變年份和月份的時(shí)候在重新綁定一次不就完了,當(dāng)然這樣也是可以的。但是不建議,簡(jiǎn)單的事情不要復(fù)雜化,無(wú)端增加開(kāi)銷。

時(shí)間選擇器顯示隱藏

??這個(gè)小功能點(diǎn),很簡(jiǎn)單,沒(méi)啥可講。需要注意多個(gè)實(shí)例并且只有一個(gè)時(shí)間選擇器的dom結(jié)構(gòu)的情況下,你該如何設(shè)計(jì)你的顯示隱藏。

結(jié)語(yǔ)

??到這里我們就把整個(gè)時(shí)間選擇控件實(shí)現(xiàn)整個(gè)思路都理了一遍,相信同學(xué)們已經(jīng)知道如何實(shí)現(xiàn)一個(gè)時(shí)間選擇控件了。快去自己動(dòng)手做一個(gè)自己專屬的時(shí)間選擇控件吧?。╬s:如果覺(jué)得本文寫的不錯(cuò),請(qǐng)記得點(diǎn)贊哦?。?/p>

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/87225.html

相關(guān)文章

  • 2017-08-12 前端日?qǐng)?bào)

    摘要:前端日?qǐng)?bào)精選中的操作符譯理解教程構(gòu)建一個(gè)預(yù)渲染友好的應(yīng)用示例譯如何學(xué)習(xí)開(kāi)發(fā)如何編寫輕量級(jí)框架中文譯后臺(tái)運(yùn)行實(shí)戰(zhàn)手冊(cè)分析器入門博客眾成翻譯一款簡(jiǎn)單到極致的數(shù)據(jù)流框架使用組件的四個(gè)技巧關(guān)鍵請(qǐng)求教程奇舞周刊第期前端路上的旅行如何只用完 2017-08-12 前端日?qǐng)?bào) 精選 JSX中的spread操作符【譯】理解Service WorkerVue.js教程: 構(gòu)建一個(gè)預(yù)渲染SEO友好的應(yīng)用示例...

    zhiwei 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<