1. It is a time selection plug-in found online as shown in the picture. Click on the date to pop up the box below. When ionic is started for the first time, this page will not be refreshed. $ionicScrollDelegate.getScrollPosition() cannot obtain the height. If scrollTo is used method, the height will be fixed to the height you jump to directly, and you cannot get the height no matter how you pull the slider. But if you refresh the page, you can get it. I found the reason for not finding it all afternoon, which is very troublesome for you.
2. I have used the resize() method, but it seems to have no effect.
3. A lot of code:
(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);
On the html side, I just used some instructions and set the initial time without too many operations.
阿神2017-05-15 17:09:21
1. If Ionic is published as an application, its input supports the mobile phone’s native DatePicker. So there is no need to use this.
2. If you don’t want to use the native picker or want to implement it on the web page, the official has provided ionic datepicker, or datepicker-for-ionic on NPM.
PS: It was originally a flat ground. You had to dig a hole and jump down yourself, and then ask others how to climb up... Just grab a picker online and use it. You have to adjust compatibility and fill holes, which only reduces efficiency. Ionic 2 already comes with DataPicker.