ionic1滑動時間選擇器


上圖:

1.derective代碼

.directive('monthPicker', function ($ionicScrollDelegate) {
            return {
                restrict: 'E',
                templateUrl: 'component/tab_bill/month-picker.html',
                scope: {
                    localDate: '='
                },
                link: function ($scope) {
                    var yearIndex = 0, year = new Date().getFullYear() + 2, localYear = new Date().getFullYear(),
                        localMonth = month = new Date().getMonth() + 1, localDay = new Date().getDate();
                    var monthIndex = 0, month = new Date().getMonth() + 1;
                    if (month < 10) {
                        month = '0' + month
                    }
                    if (localMonth < 10) {
                        localMonth = '0' + localMonth;
                    }
                    if (localMonth < 10) {
                        localDay = '0' + localDay;
                    }
                    var dayIndex = 0;
                    $scope.years = []; // 年數組
                    $scope.months = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'];
                    $scope.days = [];
                    var spar = {
                        28: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28'],
                        29: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29'],
                        30: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30'],
                        31: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31']
                    };
                    // $scope.hasDate = false; // 是否選擇需要選擇日期
                    $scope.changeFlag = 1; // 1是開始時間,2是結束時間
                    for (var i = 2000; i <= year; i++) {
                        $scope.years.push(i)
                    }
                    var loop1, loop2, loop3;
                    var checkTag = 0, checkTag2 = 0, checkTag3 = 0;
                    var _endDay, _endYear, _endMonth;

                    $scope.goChoose = function () {
                        $scope.blockFlag = true;
                        setTimeout(function () {
                          _initScroll()
                        },300)
                    };

                    $scope.$on('initPicker', function (scope, unReset) {
                        if (!unReset) {
                            $scope.localDate = angular.extend($scope.localDate, {
                                startYear: localYear,
                                startMonth: localMonth,
                                startDay: localDay,
                                endYear: localYear,
                                endMonth: localMonth,
                                endDay: localDay
                            });
                            _initScroll();
                            return;
                        }

                        _endDay = $scope.localDate.endDay;
                        _endYear = $scope.localDate.endYear;
                        _endMonth = $scope.localDate.endMonth;
                        _initScroll();
                    });

                    $scope.check1 = function () {
                        clearInterval(loop1);
                        if (checkTag < 0) {
                            return false;
                        }
                        checkTag = 0;
                        loop1 = setInterval(function () {
                            checkTag++;
                            if (checkTag > 2) {
                                chooseYear();
                                checkTag = -1;
                            }
                        }, 100)
                    };
                    $scope.check2 = function () {
                        clearInterval(loop2);
                        if (checkTag2 < 0) {
                            return false;
                        }
                        checkTag2 = 0;
                        loop2 = setInterval(function () {
                            checkTag2++;
                            if (checkTag2 > 2) {
                                chooseMonth();
                                checkTag2 = -1;
                            }
                        }, 100)
                    };
                    $scope.check3 = function () {
                        clearInterval(loop3);
                        if (checkTag3 < 0) {
                            return false;
                        }
                        checkTag3 = 0;
                        loop3 = setInterval(function () {
                            checkTag3++;
                            if (checkTag3 > 2) {
                                chooseDay();
                                checkTag3 = -1;
                            }
                        }, 100)
                    };
                    $scope.changeType = function () {
                        if ($scope.hasDate) {
                            $scope.hasDate = !$scope.hasDate;
                            $scope.blockFlag = false;
                            $scope.localDate = angular.extend($scope.localDate, {
                                startYear: '',
                                startMonth: '',
                                startDay: '',
                                endYear: '',
                                endMonth: '',
                                endDay: ''
                            });
                            return;
                        }
                        $scope.hasDate = !$scope.hasDate;
                        if ($scope.hasDate) {
                            $scope.localDate = angular.extend($scope.localDate, {
                                startYear: localYear,
                                startMonth: localMonth,
                                startDay: localDay,
                                endYear: localYear,
                                endMonth: localMonth,
                                endDay: localDay
                            });
                            $scope.days = spar[getDaysInOneMonth(localYear, localMonth)];
                            setTimeout(function () {
                                _initScroll()
                            },100)
                        } else {
                            $scope.localDate.startYear = $scope.localDate.endYear;
                            $scope.localDate.startMonth = $scope.localDate.endMonth;
                            $scope.localDate.startDay = $scope.localDate.endDay;
                            _initScroll()
                        }
                    };
                    $scope.setDate = function () {
                        if ($scope.changeFlag === 1) {
                            $scope.localDate.startYear = $scope.years[yearIndex];
                            $scope.localDate.startMonth = $scope.months[monthIndex];
                            if (!$scope.hasDate) {
                                $scope.localDate.endYear = $scope.years[yearIndex];
                                $scope.localDate.endMonth = $scope.months[monthIndex];
                                $scope.localDate.startDay = '01';
                                $scope.localDate.endDay = getDaysInOneMonth($scope.years[yearIndex], $scope.months[monthIndex]);
                            } else {
                                $scope.localDate.startDay = $scope.days[dayIndex];
                            }
                        } else {
                            $scope.localDate.endYear = $scope.years[yearIndex];
                            $scope.localDate.endMonth = $scope.months[monthIndex];
                            $scope.localDate.endDay = $scope.days[dayIndex];
                        }
                        console.log($scope.localDate)
                    };

                    $scope.setTime = function (num, _year, _month, _day) {
                        $scope.changeFlag = num;
                        if (!_year) {
                            _year = $scope.localDate.startYear;
                            _month = $scope.localDate.startMonth;
                            _day = $scope.localDate.startDay;
                        }
                        $ionicScrollDelegate.$getByHandle('scroll1').scrollTop();
                        $ionicScrollDelegate.$getByHandle('scroll2').scrollTop();
                        $ionicScrollDelegate.$getByHandle('scroll3').scrollTop();
                        _animation(_year, _month, _day)
                    };
                    function chooseYear() {
                        var top = $ionicScrollDelegate.$getByHandle('scroll1').getScrollPosition().top;
                        yearIndex = (top / 44).toFixed(0);
                        $ionicScrollDelegate.$getByHandle('scroll1').scrollTo(0, yearIndex * 44);
                        _initDate();
                        $scope.setDate();
                        setTimeout(function () {
                            checkTag = 0;
                            clearInterval(loop1);
                            $scope.$apply();
                        }, 100)
                    }

                    function chooseMonth() {
                        var top = $ionicScrollDelegate.$getByHandle('scroll2').getScrollPosition().top;
                        monthIndex = (top / 44).toFixed(0);
                        $ionicScrollDelegate.$getByHandle('scroll2').scrollTo(0, monthIndex * 44);
                        _initDate();
                        $scope.setDate();
                        setTimeout(function () {
                            checkTag2 = 0;
                            clearInterval(loop2);
                            $scope.$apply();
                        }, 100)
                    }

                    function chooseDay() {
                        var top = $ionicScrollDelegate.$getByHandle('scroll3').getScrollPosition().top;
                        dayIndex = Number((top / 44).toFixed(0));
                        $ionicScrollDelegate.$getByHandle('scroll3').scrollTo(0, dayIndex * 44);
                        $scope.setDate();
                        setTimeout(function () {
                            checkTag3 = 0;
                            clearInterval(loop3);
                            $scope.$apply();
                        }, 100)
                    }

                    function _animation(year, month, day) {
                        $ionicScrollDelegate.$getByHandle('scroll1').scrollTop();
                        $ionicScrollDelegate.$getByHandle('scroll2').scrollTop();
                        for (var i = 0; i < $scope.years.length; i++) {
                            if ($scope.years[i] == year) {
                                yearIndex = i;
                                $ionicScrollDelegate.$getByHandle('scroll1').scrollTo(0, yearIndex * 44);
                            }
                        }
                        for (var j = 0; j < 12; j++) {
                            if ($scope.months[j] == month) {
                                monthIndex = j;
                                $ionicScrollDelegate.$getByHandle('scroll2').scrollTo(0, monthIndex * 44);
                            }
                        }
                        if (day) {
                            for (var k = 0; k < 32; k++) {
                                if ($scope.days[k] == day) {
                                    dayIndex = k;
                                    $ionicScrollDelegate.$getByHandle('scroll3').scrollTo(0, dayIndex * 44);
                                }
                            }
                        }
                    }

                    function _initDate() {
                        var sparNum = getDaysInOneMonth($scope.years[yearIndex], $scope.months[monthIndex]);
                        $scope.days = spar[sparNum];
                        if (dayIndex + 1 > sparNum) {
                            for (var k = 0; k < 32; k++) {
                                if ($scope.days[k] == sparNum) {
                                    dayIndex = k;
                                    $ionicScrollDelegate.$getByHandle('scroll3').scrollTo(0, dayIndex * 44);
                                }
                            }
                        }
                    }

                    function getDaysInOneMonth(year, month) {
                        month = parseInt(month, 10);
                        var d = new Date(year, month, 0);
                        return d.getDate();
                    }

                    function _initScroll() {
                        if (!$scope.blockFlag) {
                            return;
                        }
                        $scope.changeFlag = 1;

                        if ($scope.hasDate) {
                            _animation($scope.localDate.startYear, $scope.localDate.startMonth, $scope.localDate.startDay)
                            return
                        }

                        if (_endDay) {
                            $scope.localDate = angular.extend($scope.localDate, {
                                startYear: '',
                                startMonth: '',
                                startDay: '',
                                endYear: '',
                                endMonth: '',
                                endDay: ''
                            });
                            _animation(_endYear,_endMonth);
                            return;
                        }
                        _animation(localYear,month)


                    }
                }
            };
        }
    );

  2.html代碼

<div class="switch-btn-zx" ng-click="changeType()" ng-if="blockFlag">
    {{hasDate?'按日選擇':'按月選擇'}}
</div>
<div class="switch-btn-zx" ng-click="goChoose()" ng-if="!blockFlag">
    未篩選
</div>
<div id="month-picker" ng-if="blockFlag">
    <div class="title" ng-if="!hasDate">{{localDate.endYear?localDate.endYear + '-' + localDate.endMonth:localDate.endDay + '-' + localDate.startMonth}}</div>
    <div class="title1" ng-if="hasDate">
        <span ng-click="setTime(1,localDate.startYear,localDate.startMonth,localDate.startDay)" ng-class="{'active': changeFlag == 1}">
            {{localDate.startYear + '-' + localDate.startMonth + '-' + localDate.startDay}}
        </span>
        <span>至</span>
        <span ng-click="setTime(2,localDate.endYear,localDate.endMonth,localDate.endDay)" ng-class="{'active': changeFlag == 2}">
            <span ng-if="localDate.endYear" style="border-bottom:0" >{{localDate.endYear + '-' + localDate.endMonth + '-' + localDate.endDay}}</span>
            <span ng-if="!localDate.endYear" style="color:#666;border-bottom:0">結束日期</span>
        </span>
    </div>
    <div class="select-container">
        <div class="hook">
            <ion-scroll scrollbar-y="false" delegate-handle="scroll1" on-scroll="check1()">
                <ul>
                    <li ng-repeat="year in years">{{year}}年</li>
                </ul>
            </ion-scroll>
            <div class="picker-center-highlight"></div>
        </div>
        <div class="hook">
            <ion-scroll scrollbar-y="false" delegate-handle="scroll2" on-scroll="check2()">
                <ul>
                    <li ng-repeat="month in months">{{month}}月</li>
                </ul>
            </ion-scroll>
            <div class="picker-center-highlight"></div>
        </div>
        <div class="hook"  ng-if="hasDate">
            <ion-scroll scrollbar-y="false" delegate-handle="scroll3" on-scroll="check3()">
                <ul>
                    <li ng-repeat="day in days">{{day}}日</li>
                </ul>
            </ion-scroll>
            <div class="picker-center-highlight"></div>
        </div>
    </div>
</div>

  3.scss代碼

#month-picker {
  width: 5.4rem;
  height: (378px/2);
  border-radius: 0.1rem;
  padding: 6px 6px 0px 6px;
  background: rgba(72, 128, 237, 0.06);
  position: relative;
  .title {
    height: 50px;
    line-height: 50px;
    border-bottom: 1px solid #4880ED;
    color: #4880ED !important;
    text-align: center;
    font-size: 0.4rem !important;
  }
  .title1 {
    height: 50px;
    line-height: 50px;
    color: #aaa !important;
    text-align: center;
    font-size: 0.4rem !important;
    display: -webkit-flex;
    display: flex;
    span:first-child, span:last-child {
      -webkit-flex: 1;
      flex: 1;
    }
    span:nth-child(2) {
      width: 0.5rem;
      font-size: 0.28rem;
    }
    .active {
      color:#4880ED !important;
      font-weight: 500;
      border-bottom: 1px solid #4880ED;
    }
  }
  .select-container {
    display: -webkit-flex;
    display: flex;
    position: relative;
    .hook {
      -webkit-flex: 1;
      flex: 1;
      height: (44*3px);
      position: relative;
      z-index: 33!important;
    }
    ion-scroll {
      width: 100%;
      height: 100%;
      z-index: 1!important;
      .scroll {
        z-index: 1!important;
      }
      ul {
        padding: 44px 0;
        background: rgba(72, 128, 237, 0.12);
      }
      li {
        height: 44px;
        text-align: center;
        line-height: 44px;
        font-size: 0.4rem;
        color: #000;
      }
    }
  }
  .picker-center-highlight {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 132px;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    margin-top: 0;
    pointer-events: none;
    z-index: 3333;
    &:after {
      content: '';
      width: 100%;
      height: 44px;
      position: absolute;
      left: 0;
      top: 50%;
      margin-top: -22px;
      z-index: 33333;
      background-image: -webkit-linear-gradient(top, #d0d0d0, #d0d0d0, transparent, transparent), -webkit-linear-gradient(bottom, #d0d0d0, #d0d0d0, transparent, transparent);
      background-image: linear-gradient(180deg, #d0d0d0, #d0d0d0, transparent, transparent), linear-gradient(0deg, #d0d0d0, #d0d0d0, transparent, transparent);
      background-position: top, bottom;
      background-size: 100% 1px;
      background-repeat: no-repeat;
    }
    &:before {
      height: 100%;
      margin: 0 auto;
      z-index: 333333;
      background-image: -webkit-linear-gradient(top, hsla(0, 0%, 100%, .8), hsla(0, 0%, 100%, .4)), -webkit-linear-gradient(bottom, hsla(0, 0%, 100%, .8), hsla(0, 0%, 100%, .4));
      background-image: linear-gradient(180deg, hsla(0, 0%, 100%, .8), hsla(0, 0%, 100%, 0.4)), linear-gradient(0deg, hsla(0, 0%, 100%, .8), hsla(0, 0%, 100%, .4));
      background-position: top , bottom;
      background-size: 100% 44px;
      background-repeat: no-repeat;
      position: absolute;
      left: 0;
      top: 0;
      content: '';
      width: 100%;
    }
  }
}

.switch-btn-zx {
  width: 1.74rem;
  height: 0.48rem;
  border-radius: 1rem;
  background: rgba(72, 128, 237, 0.06);
  border: 1px solid #4880ED;
  font-size: 0.24rem;
  color: #4880ED;
  padding: 0.08rem 0 0.13rem 0.2rem;
  background: url('../img/switch.png') no-repeat 1.23rem center;
  background-size: 0.32rem 0.32rem;
  margin-bottom: 0.2rem;
}

  4.controller用法

 $scope.localDate = {};  // 初始化時間選擇插件對象
 
$scope.$broadcast('initPicker', true); // 需要手動初始化的時候調用一下廣播。


在ios上scroll的層級會有問題,我在里面初始化了兩次后顯示正常。現在還找不到原因。
ionic的scroll指令在移動很短距離的時候不會觸發scroll-complete事件。所以用了一個定時器在on-scroll事件上去計算值,然后再計算移動距離。
有想法的童鞋可以指導改進一下。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM