angular.js - $ionicScrollDelegate.getScrollPosition() 在頁面第一次進入後無法取得對應的高度
大家讲道理
大家讲道理 2017-05-15 17:07:21
0
1
797

1.是一個在網上找的時間選擇插件如圖,點擊日期彈出下面的框,在第一次啟動ionic不在這個頁面進行刷新$ionicScrollDelegate.getScrollPosition() 無法獲取到高度,如果用了scrollTo方法,高度會固定到你直接跳躍的高度,無論你如何拉動滑條都沒辦法取得到高度。但如果進行一次頁面刷新就能取得到了,找到一個下午原因沒找到,麻煩各位大大了。

2.用過resize()方法,但是看起來沒什麼效果。
3.代碼很多:

(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);

html那邊只是用了一下指令和設定了一下初始時間沒有過多的操作。

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全部回覆(1)
阿神

1.Ionic如果發布成應用,本身Input是支援手機原生的DatePicker的。所以沒有必要使用這個。
2.如果不想用原生picker或想在網頁上也能實現,官方已經提供ionic datepicker,或者NPM上的datepicker-for-ionic。

PS:原本是個平地,你非要挖坑自己跳下去,然後問別人怎麼爬上來...網上隨便抓個picker拿來就用,又要調兼容又要填坑,只是降低效率。 Ionic 2已經自備DataPicker了。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板