自定義樣式的日期選擇器|開發者進階之路
~每周最期待的周五又來啦!提前祝小伙伴們周末愉快呀!按照慣例,繼續分享我們《30天自定義時間選擇器,App開發從0到1》內容。本周為大家精選的章節是第二部分第八章第一小節——自定義樣式的日期選擇器。敲黑板!!!感興趣的小伙伴帶上小板凳上課啦!
學習目標:
實現自定義樣式的日期選擇器
以下示例講解僅選擇部分核心代碼進行詳細說明,讀者可在 本書的資源范例中獲取示例的完整代碼。
8.1
自定義樣式的日期選擇器
模塊因其易用性、高效性,在 應用開發中會被頻繁地使用。UI 類的 模塊,可以修改顏色、字體、背景色等樣式,形成不同的風格與外觀樣式,但模塊的整體布局結構是無法改變的。本示例提供一種思路,將 HTML 頁面與模塊混合搭配,利用HTML 快速布局形成不同的頁面格局,形成另類的視覺體驗。
下面采用 HTML 頁面與 模塊混合嵌套的方式,實現一個不一樣的日期選擇器自定義時間選擇器,如圖 8-1 所示。
圖 8-1
8.1.1
使用模塊
模塊是一個自定義內容選擇器,可自定義模塊位置、內容取值范圍、內容標簽、設置選中內容,還可用于實現固定取值范圍的內容選擇器;多項內容之間沒有級聯關系。
8.1.2
開發流程及要點概述
本示例的實現思路是先用 HTML 代碼創建一個背景頁面,然后將模塊打開在這個背景層上面,從而從視覺上實現既定的目標樣式。
(1)實現 HTML 靜態頁面開發
為相關頁面添加如下 HTML 代碼,使用了彈性盒子布局。篇幅所限,CSS 樣式部分就不在這里列出,具體可從示例源碼中獲取查看。注意頁面中的 點擊事件使用了 屬性去消除 300 ms 的點擊延遲。
請選擇日期
完成
年
月
日
取消
(2)創建日期選擇器
創建模塊實例,在 open 方法中定義了模塊的位置、大小尺寸和顏色樣式、可選的時間范圍等參數。在 open 方法的回調中記錄了模塊的 ID 值,用于后續操作模塊的邏輯方法時使用。同時加入了設置模塊初始化顯示的默認值方法和防止選擇錯誤日期(如 2 月 30 日)的方法。
為相關頁面添加如下代碼:
// 部分代碼
var ; //模塊對象
var ; // 記錄當前模塊ID的變量
() { // 創建聯動選擇器
= api.(''); // 引入模塊
// 定義模塊初始化需要的參數
// 根據頁面HTML布局,定義模塊所在位置參數
var tY = api. - 184 - 10; // 定義模塊rect中的Y,起始高度數值
var tW = api. - 40; // 定義模塊rect中的w,寬度數值
// 定義模塊可選擇的時間范圍參數
// 獲取當前年份
var tNow = new Date();
var tYear = tNow.(); // 獲取當前年份
var = tNow.(); // 獲取當前月份
var tDate = tNow.(); // 獲取當前日期
var = tYear - 100; // 可選最小時間,100年前
var = tYear + 100; // 可選最大時間,100年后
.open({
rect: {
x: 20,
y: tY,
w: tW,
h: 135
},
: {
bg: 'rgba(61,61,61,0.0)',
: 'rgba(61,61,61,0.5)',
: '#',
: 28,
: '#',
: 16
},
data: [{
scope: + '-' +
}, {
scope: '1-12'
}, {
scope: '1-31'
}],
: false,
loop: true,
rows: 3,
fi xedOn: api.,
fi xed: true
}, (ret, err) {
if (ret) {
if('' == ret.id) {
= ret.id; // 記錄當前模塊的ID
}
if('show' === ret.) {
// 設置當前時間為默認值
var = [tYear,+1,tDate];
();
}
if('' === ret.) {
//判斷選擇值的合法性
(ret.data);
}
}
});
}
(3)加入時間校驗邏輯
因為現實時間存在閏年,并且每個月的天數不同,所以需要完善日期選擇器,加上補充邏輯,以避免出現選擇了 ×××× 年 2 月 31 日的錯誤發生。
/**
* 閏年判斷
* @param {} pYear 4位數字組成的年份值
* @
*/
Date.. = (pYear) {
var self = this;
var tYear = '' === pYear ? pYear:self.();
(tYear % 4 == 0) && (tYear % 100 != 0 || tYear % 400 == 0);
}
var ; // 選擇的時間數組
/**
* 判斷選擇值的合法性
* @param {Array} pData 日期選擇器選擇后的回調數據
* @ {void}
*/
(pData) {
if('[ Array]' !== ...call(pData)) {
;
}
//判斷特殊日期
//獲取月份進行判斷
var tData = pData;
(tData[1]) {
case '2':
//判斷是否為閏年
var tNum = '28';
if(new Date().(tData[0])){
tNum = '29';
}
if( (tData[2]) > (tNum) ){
tData[2] = tNum;
(tData);
}
else {
= tData;
}
break;
case '4':
case '6':
case '9':
case '11':
if( tData[2] == '31') {
tData[2] = '30';
(tData);
}
else {
= tData;
}
break;
:
= tData;
}
}
/**
* 主動設置選擇器的選擇值
* @param {Array} pData 日期選擇器選擇后的回調數據
* @ {void}
*/
(pData) {
if('[ Array]' !== ...call(pData)) {
;
}
.({
id: ,
data: pData
});
= pData;
}
(4)加入 HTML 頁面按鈕點擊事件
點擊事件是實現模塊和其他頁面的交互邏輯的。
() 函數方法中使用了 api. 這個 api 的屬性,其中 ( 表示回調的 win 窗口名稱 ) 和 (表示回調的 frame 窗口名稱),具體對應的值是上一級打開本頁面的窗口傳送過來的,這樣的好處是方便本頁面封裝成一個通用的公共頁面,更加靈活。
為相關頁面添加如下 JS 代碼:
//取消按鈕點擊事件
() {
api.({ // 調用上級頁面方法來關閉選擇器
name: api..,
: api..,
: '();'
});
}
() 完成按鈕的點擊事件,將關閉頁面的方法放在了上級頁面,使用 api. 方法去調用執行。這樣處理是為了避免頁面關閉的執行過快,后續的邏輯代碼還沒來得及執行或沒有執行完,從而產生錯誤異常。
//完成按鈕點擊
() {
if(! || . == 0) {
api.toast({
msg: '請選擇日期!',
: 2000,
: ''
});
;
}
else {
/* 執行完成后續業務邏輯 */
// .log('選擇數據:'+JSON.());
api.({ //執行選擇后的回調方法
name: api..,
: api..,
: api..+'('+JSON.()+');'
});
}
}
本示例的點擊事件中使用的 api. 對象是由上級頁面傳遞的,目的是將頁面選擇的數據回傳給調用的上級頁面。