1. Ia adalah pemalam pemilihan masa yang ditemui dalam talian seperti yang ditunjukkan dalam gambar .getScrollPosition() tidak boleh mendapatkan ketinggian Jika kaedah scrollTo digunakan, ketinggian akan ditetapkan pada ketinggian yang anda lompat terus dan anda tidak boleh mendapatkan ketinggian tidak kira bagaimana anda menarik peluncur. Tetapi jika anda memuat semula halaman, anda boleh mendapatkannya. Saya dapati sebab tidak menemuinya sepanjang petang, yang sangat menyusahkan anda.
2. Saya telah menggunakan kaedah resize(), tetapi nampaknya tiada kesan.
3. Banyak kod:
(function () {
'use strict';
angular.module('CoderYuan', [])
.service('timePickerService', function () {
var _this = this;
//页面中选择器数量 default : 0
_this.globalId = 0;
return _this;
})
/*日期时间选择*/
.directive('timePicker', [
'$timeout',
'$compile', '$ionicScrollDelegate', '$ionicBackdrop', '$q', 'timePickerService',
function ($timeout, $compile, $ionicScrollDelegate, $ionicBackdrop, $q, timePickerService) {
return {
// template: '<p>{{selectDateTime.show}}</p>',
restrict: 'AE',
replace: true,
scope: {
timePickerResult: '=', //双向绑定
loadDateTime: '=', // 用于从服务端加载(或其他方式加载时间,反正是延迟的就对了) 初始 时间日期数值 //要配合options 中的loadLazy 属性使用 如果默认时间是从服务端加载回来的
//要做如下设置 <time-picker load-date-time="data.dateTime" loadLazy="true" time-picker-result="result"></time-picker>
//即 loadLazy 设置为true(默认是false)标识时间数据延迟加载 data.dateTime 是从服务端加载回来的时间数据
},
link: function (scope, elm, attrs) {
var globalId = ++timePickerService.globalId;
var dateTimeNow = new Date();
var tem = "<p class='pickerContainer datetimeactive'>" +
"<p class='main'>" +
"<p class='header'>{{options.title}}</p>"
+ "<p class='body'>"
+ "<p class='row row-no-padding'>" +
"<p class='col' ng-if='!options.hideYear' ><ion-scroll on-scroll='scrollingEvent(\"year\")' delegate-handle='yearScroll_" + globalId + "' scrollbar-y='false' class='yearContent'>" + "<ul>" + "<li ng-style='year.selected ? { color: \"#000\",fontWeight: \"bold\", fontSize: \"1.2em\"}:{}' ng-click='selectEvent(\"year\",$index)' ng-repeat='year in yearList'>{{year.text}}</li>" + "</ul>" + "</ion-scroll></p>" +
"<p class='col' ng-if='!options.hideMonth' ><ion-scroll on-scroll='scrollingEvent(\"month\")' delegate-handle='monthScroll_" + globalId + "' scrollbar-y='false' class='monthContent'>" + "<ul>" + "<li ng-style='month.selected ? { color: \"#000\",fontWeight: \"bold\", fontSize: \"1.2em\"}:{}' ng-click='selectEvent(\"month\",$index)' ng-repeat='month in monthList'>{{month.text}}</li>" + "</ul>" + "</ion-scroll></p>" +
"<p class='col ' ng-if='!options.hideDate' ><ion-scroll on-scroll='scrollingEvent(\"date\")' delegate-handle='dateScroll_" + globalId + "' scrollbar-y='false' class='dateContent'>" + "<ul>" + "<li ng-style='date.selected ? { color: \"#000\",fontWeight: \"bold\", fontSize: \"1.2em\"}:{}' ng-click='selectEvent(\"date\",$index)' ng-repeat='date in dateList'>{{date.text}}</li>" + "</ul>" + "</ion-scroll></p>" +
"</p>"
+ "<p class='body_center_highlight'></p>" +
"</p>" +
"<p class='footer'>" +
"<span ng-click='ok()'>确定</span><span ng-click='cancel()'>取消</span>" +
"</p>" +
"</p>" +
"</p>";
var options = {
title: attrs.title || "时间选择",
height: 40,// 每个滑动 li 的高度 这里如果也配置的话 要修改css文件中的高度的定义
timeNum: parseInt(attrs.timenum) || 24,//可选时间数量
yearStart: (attrs.yearstart && parseInt(attrs.yearstart)) || dateTimeNow.getFullYear() - 80,//开始年份
yearEnd: (attrs.yearend && parseInt(attrs.yearend)) || dateTimeNow.getFullYear() , //结束年份
monthStart: 12,//开始月份
monthEnd: 1,//结束月份
DateTime: attrs.datetime && new Date(attrs.datetime) || dateTimeNow, //开始时间日期 不给默认是当天
timeSpan: attrs.timespan && parseInt(attrs.timespan) || 15, //时间间隔 默认 15分钟一个间隔 15/30
hideYear: attrs.hideyear || false, //选择器中隐藏年份选择栏
hideMoth: attrs.hidemoth || false,//选择器中隐藏月份选择栏
hideDate: attrs.hidedate || false,//选择器中隐藏日期选择栏
}
scope.options = options;
scope.yearScrollTimer = null; //年份滑动定时器
scope.monthScrollTimer = null; //月份滑动定时器
scope.dateScrollTimer = null; //日期滑动定时器
scope.dateList = [];
scope.yearList = [];
scope.monthList = [];
scope.selectDateTime = {
year: {item: null, index: 0},
month: {item: null, index: 0},
date: {item: null, index: 0},
show: ""
};
scope.specialDateTime = {
bigMoth: [1, 3, 5, 7, 8,10, 12],
isBigMonth: function (month) {
var length = this.bigMoth.length;
while (length--) {
if (this.bigMoth[length] == month) {
return true;
}
}
return false;
},
isLoopYear: function (year) { //是否是闰年
return (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0);
}
};
//进行属性获取和初始化
scope.options = options;
init(options);
elm.on("click", function () {
show();
// scrollToElm(scope.yearScroll, scope.yearList[scope.selectDateTime.year.index - 3]);
// scrollToElm(scope.monthScroll, scope.monthList[scope.selectDateTime.month.index - 3]);
// scrollToElm(scope.dateScroll, scope.dateList[scope.selectDateTime.date.index - 3]);
$ionicScrollDelegate.resize();
});
//滑动Event
scope.scrollingEvent = function (type) {
var opEntity = getOperateEntity(type);
//当前存在滑动则取消
scope[opEntity.scrollTimer] && $timeout.cancel(scope[opEntity.scrollTimer]);
var posi = scope[opEntity.scrollHandler].getScrollPosition();
console.log(opEntity.scrollHandler+" "+scope+" "+scope[opEntity.scrollHandler]);
var index = Math.abs(Math.round(posi.top / scope.options.height));
console.log(index+" "+scope.options.height+" "+posi.top);
if (posi.top == index * scope.options.height) {
// console.log("meijinru gundong ");
updateSelect(index + 3, type);
} else {
// console.log("jinru gundong ");
scope[opEntity.scrollTimer] = $timeout(function () {
posi.top = index * 40;
updateSelect(index + 3, type);
scrollToPosi(scope[opEntity.scrollHandler], posi);
}, 200);
}
}
//点击Event
// scope.selectEvent = function (type, index) {
// var opEntity = getOperateEntity(type);
// if (index > 2 && index <= scope[opEntity.data].length - 3) {
// scrollToElm(scope[opEntity.scrollHandler], scope[opEntity.data][index - 3]);
// }
// }
//初始化
function init(options) {
initYear(options);
initMoth(options);
initDate(options);
tem = angular.element(tem);
$compile(tem)(scope);
angular.element(document.body).append(tem);
scope.yearScroll = $ionicScrollDelegate.$getByHandle("yearScroll_" + globalId);
scope.monthScroll = $ionicScrollDelegate.$getByHandle("monthScroll_" + globalId);
scope.dateScroll = $ionicScrollDelegate.$getByHandle("dateScroll_" + globalId);
setDateTimeShow(options.DateTime);
}
//从其他地方传来的日期初始化
function setDateTimeShow(datetime){
var year = datetime.getFullYear();
var month = prependZero(datetime.getMonth()+1,10);
var date = prependZero(datetime.getDate(),10);
scope.timePickerResult = year+"-"+month+"-"+date;
}
//年份初始化
function initYear(options) {
var defaultYear = options.DateTime.getFullYear();
var yearSpan = options.yearEnd - options.yearStart;
console.log(defaultYear+" "+yearSpan);
var text, data, top, item, defaultItem, defaultIndex;
console.log(options.height);
prependLi(scope.yearList, 3, "b");
for (var i = 0; i <= yearSpan; i++) {
text = options.yearStart + i + "年";
data = options.yearStart + i;
top = options.height + scope.yearList[scope.yearList.length - 1].top;
item = createDateTimeLi(0, top, data, data == defaultYear, text);
if (data == defaultYear) {
defaultItem = item;
defaultIndex = scope.yearList.length;
}
scope.yearList.push(item);
}
//设置默认选择
scope.selectDateTime.year.item = defaultItem;
scope.selectDateTime.year.index = defaultIndex;
prependLi(scope.yearList, 3, "e");
$ionicScrollDelegate.resize();
}
//月份初始化
function initMoth(options) {
var defaultMonth = options.DateTime.getMonth() + 1 == 0 ? 12 : prependZero(options.DateTime.getMonth() + 1, 10);
var text, data, original, top, item, defaultItem, defaultIndex;
prependLi(scope.monthList, 3, "b");
for (var i = 1; i <= 12; i++) {
original = i;
data = prependZero(i, 10);
text = prependZero(i, 10) + "月";
top = options.height + scope.monthList[scope.monthList.length - 1].top;
item = createDateTimeLi(0, top, data, data == defaultMonth, text);
if (data == defaultMonth) {
defaultItem = item;
defaultIndex = scope.monthList.length;
}
scope.monthList.push(item);
}
//设置默认选择
scope.selectDateTime.month.item = defaultItem;
scope.selectDateTime.month.index = defaultIndex;
prependLi(scope.monthList, 3, "e");
$ionicScrollDelegate.resize();
}
//日期初始化
function initDate(options) {
//开始时间
var defaultDate = prependZero(options.DateTime.getDate(), 10);
var text, data, top, item, defaultItem, defaultIndex;
var dateNum = getDateNum(options.DateTime.getFullYear(), options.DateTime.getMonth() + 1);
prependLi(scope.dateList, 3, "b")
for (var i = 1; i <= dateNum; i++) {
data = prependZero(i, 10);
text = prependZero(i, 10) + "日";
top = options.height + scope.dateList[scope.dateList.length - 1].top;
item = createDateTimeLi(0, top, data, data == defaultDate, text);
if (data == defaultDate) {
defaultItem = item;
defaultIndex = scope.dateList.length;
}
scope.dateList.push(item);
}
//设置默认选择
scope.selectDateTime.date.item = defaultItem;
scope.selectDateTime.date.index = defaultIndex;
prependLi(scope.dateList, 3, "e");
}
function prependZero(data, num) {
return data >= num ? data : "0" + data;
}
function createDateTimeLi(left, top, data, selected, text) {
var li = {left: left, top: top, data: data, selected: selected, text: text};
return li;
}
function prependLi(arr, num, loc) {
loc = loc || "b";
switch (loc) {
case "b":
for (var i = 0; i < num; i++) {
arr.push(createDateTimeLi(0, options.height * i, "", false, ""));
}
break;
case "e":
//最后那个li元素的 top
var lastPosiTop = arr[arr.length - 1].top;
for (var j = 0; j < num; j++) {
arr.push(createDateTimeLi(0, (options.height * (j + 1) + lastPosiTop), "", false, ""));
}
break;
}
}
//滑动到指定元素
function scrollToElm(scorllHandler, elm) {
$timeout(function(){scorllHandler.scrollTo(elm.left, elm.top, true)},2000);
}
//滑动到指定位置
function scrollToPosi(scorllHandler, posi) {
scorllHandler.scrollTo(posi.left, posi.top, true);
}
function updateSelect(index, type) {
switch (type) {
case "year":
//强制
$timeout(function () {
scope.selectDateTime.year.item.selected = false;
scope.yearList[index].selected = true;
scope.selectDateTime.year.item = scope.yearList[index];
scope.selectDateTime.year.index = index;
resettingDate(scope.selectDateTime.year.item.data, parseInt(scope.selectDateTime.month.item.data)); //年份变化 重置日期栏
},200);
break;
case "month":
//强制
$timeout(function () {
scope.selectDateTime.month.item.selected = false;
scope.monthList[index].selected = true;
scope.selectDateTime.month.item = scope.monthList[index];
scope.selectDateTime.month.index = index;
resettingDate(scope.selectDateTime.year.item.data, parseInt(scope.selectDateTime.month.item.data)); //月份变化 重置日期栏
});
break;
case "date":
$timeout(function () {
scope.selectDateTime.date.item.selected = false;
scope.dateList[index].selected = true;
scope.selectDateTime.date.item = scope.dateList[index];
scope.selectDateTime.date.index = index;
});
break;
}
}
//获取选中的datetime
function getSelectDateTime() {
var year, month, date, time;
for (var i = 0; i < scope.yearList.length; i++) {
if (scope.yearList[i].selected) {
year = scope.yearList[i].data;
scope.selectDateTime.year.item = scope.yearList[i];
scope.selectDateTime.year.index = i;
break;
}
}
for (var i = 0; i < scope.monthList.length; i++) {
if (scope.monthList[i].selected) {
month = scope.monthList[i].data;
scope.selectDateTime.month.item = scope.monthList[i];
scope.selectDateTime.month.index = i;
break;
}
}
for (var i = 0; i < scope.dateList.length; i++) {
if (scope.dateList[i].selected) {
date = scope.dateList[i].data;
scope.selectDateTime.date.item = scope.dateList[i];
scope.selectDateTime.date.index = i;
break;
}
}
if (!year) {
year = scope.selectDateTime.year.item.data;
}
if (!month) {
year = scope.selectDateTime.month.item.data;
}
if (!date) {
date = scope.selectDateTime.date.item.data;
}
var value = year + "-" + month + "-" + date ;
value = new Date(value);
return value;
}
//根据年份和月份计算日期数量
function getDateNum(year, month) {
var dateNum = 30;
if (scope.specialDateTime.isBigMonth(month)) { //大小月判断
dateNum++;
} else {
if (scope.specialDateTime.isLoopYear(year)) {
if (month == 2)
dateNum--;
} else {
if (month == 2)
dateNum -= 2;
}
}
return dateNum;
}
//重置日期选择栏数据
function resettingDate(year, month) {
var dateNum = getDateNum(year, month);
if (dateNum != scope.dateList.length - 6) { //数量变化 需要进行重置
var text, data, top, item, defaultItem, defaultIndex;
var refreshNum = dateNum - (scope.dateList.length - 6)
if (refreshNum > 0) {//追加日期数量
var lastData = scope.dateList[scope.dateList.length - 4];
for (var i = 1; i <= refreshNum; i++) {
data = lastData.data + i;
text = data + "日";
top = options.height + scope.dateList[scope.dateList.length - 4].top;
item = createDateTimeLi(0, top, data, false, text);
scope.dateList.splice(scope.dateList.length - 3, 0, item);
}
} else { //移除多余的日期数量
var refreshNum_ = Math.abs(refreshNum);
scope.dateList.splice(scope.dateList.length - 4 - refreshNum_ + 1, refreshNum_);
if (scope.selectDateTime.date.item.data > scope.dateList[scope.dateList.length - 4].data) {
scope.dateList[scope.dateList.length - 4].selected = true;
scope.selectDateTime.date.item = scope.dateList[scope.dateList.length - 4];
scope.selectDateTime.date.item.index = scope.dateList.length - 4;
scrollToElm(scope.dateScroll, scope.dateList[scope.selectDateTime.date.index - 3]);
}
}
}
}
function getOperateEntity(type) {
var entity = new Object();
var scrollTimer, scrollHandler, data, defaultSelected, selectedItem;
switch (type) {
case "year":
entity.scrollTimer = "yearScrollTimer";
entity.type = type;
entity.scrollHandler = "yearScroll";
entity.data = "yearList";
entity.defaultSelected = scope.selectDateTime.year.item.data;
entity.selectedItem = "year";
break;
case "month":
entity.scrollTimer = "monthScrollTimer";
entity.type = type;
entity.scrollHandler = "monthScroll";
entity.data = "monthList";
entity.defaultSelected = scope.selectDateTime.month.item.data;
entity.selectedItem = "month";
break;
case "date":
entity.scrollTimer = "dateScrollTimer";
entity.type = type;
entity.scrollHandler = "dateScroll";
entity.data = "dateList";
entity.defaultSelected = scope.selectDateTime.date.item.data;
entity.selectedItem = "date";
break;
}
return entity;
}
scope.ok = function () {
var datetime = getSelectDateTime();
setDateTimeShow(datetime);
hide();
}
scope.cancel = function () {
hide();
}
function show() {
$ionicBackdrop.retain();
tem.css("display", "block");
}
function hide() {
tem.css("display", "none");
$ionicBackdrop.release();
}
function remove() {
tem.remove();
}
scope.$on("$destroy", function () {
remove();
})
}
}
}
]);
})(window, document);
Di bahagian html, saya hanya menggunakan beberapa arahan dan menetapkan masa awal tanpa terlalu banyak operasi.
1.Ionic如果发布成应用,本身Input是支持手机原生的DatePicker的。所以没有必要使用这个。
2.如果不想用原生picker或者想在网页上也能实现,官方已经提供ionic datepicker,或者NPM上的datepicker-for-ionic。
PS:原本是个平地,你非要挖坑自己跳下去,然后问别人怎么爬上来...网上随便抓个picker拿来就用,又要调兼容又要填坑,只是降低效率。Ionic 2已经自带DataPicker了。