Wscats / angular-tutorial

:rabbit:Some of the angular tutorial - 《Angular学习笔记》
387 stars 125 forks source link

angular下拉刷新 #12

Open Wscats opened 8 years ago

Wscats commented 8 years ago

注意这里要固定列表的高度 在组件directive中,通过获取attr的属性值中的方法名 scope.$apply(attr.whenScrolled)可以执行when-scrolled="loadMore()"中的loadMore函数

<!DOCTYPE html>
<html ng-app="wsscat">

    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <script type="text/javascript" src="../js/angular.js"></script>
    <style type="text/css">
            li {
                /*height: 120px;*/
                border-bottom: 1px solid gray;
            }

            #fixed {
                height: 500px;
                overflow: auto;
            }
        </style>
    <body ng-controller="indexCtrl">
        <div id="fixed" when-scrolled="loadMore()">
            <ul>
                <li ng-repeat="item in items">{{item}}</li>
            </ul>
        </div>
    </body>
    <script>
        var app = angular.module('wsscat', []);
        app.controller('indexCtrl', function($scope) {
            $scope.items = ['wsscat number'];
            //产生随机数组
            for(var i=0;i<=50;i++){
                $scope.items.push(Math.random()*10);
            }
            console.log($scope.items);
            $scope.loadMore = function(){
                console.log('下拉刷新更多');
            }
        })
        app.directive('whenScrolled', function() {
            return function(scope, elm, attr) {
                //内层DIV的滚动加载
                var raw = elm[0];
                console.log(scope);
                console.log(elm);
                elm.bind('scroll', function() {
                    console.log(raw.scrollTop);   //翻滚距离顶部的距离  (一直变动)   
                    console.log(raw.offsetHeight);//未翻滚前列表的高度 (一直固定)
                    console.log(raw.scrollHeight);//列表的加载完的高度 (一直固定)
                    if(raw.scrollTop + raw.offsetHeight >= raw.scrollHeight) {
                        console.log(attr.whenScrolled);//log loadMore()
                        scope.$apply(attr.whenScrolled);//执行 loadMore函数
                    }
                });
            };
        });
    </script>
</html>
Wscats commented 8 years ago
<!DOCTYPE html>
<html ng-app="wsscat">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <style>
        #fixed {
            height: 500px;
            overflow: auto;
        }
    </style>
    <script type="text/javascript" src="../js/angular.js"></script>
    <body ng-controller="indexCtrl">
        <!--组件就是一个指令 传递函数-->
        <div id="fixed" whenscrolled="loadMore()"></div>
    </body>
    <script>
        var app = angular.module('wsscat', []);
        app.controller('indexCtrl', function($scope) {
            $scope.items = ['wsscat'];
            var i = 0;
            for(; i <= 100; i++) {
                $scope.items.push(Math.random() * 10)
            }
            console.log($scope.items);
            $scope.loadMore = function() {
                var j = 0;
                for(; j <= 10; j++) {
                    $scope.items.push(Math.random() * 10)
                }
            }
        })
        app.directive('whenscrolled', function() {
            return {
                template:'<ul><li ng-repeat="item in items">{{item}}</li></ul>',
                link: function(scope, ele, attr) {
                    ele.bind('scroll', function() {
                        if(ele[0].scrollTop + ele[0].offsetHeight >= ele[0].scrollHeight) {
                            console.log("已经到最底");
                            scope.$apply(attr.whenscrolled);
                        }
                        //console.log(ele[0].scrollHeight);//1868
                        //console.log(ele[0].scrollTop);   //变化
                        //console.log(ele[0].offsetHeight);//600
                        //手动刷新
                        //scope.$apply(attr.whenscrolled);
                    })
                    scope.$apply;
                }
            }
        })
    </script>
</html>
Wscats commented 8 years ago

让下拉刷新组件自适应高度

我们根据上面可以继续改进,首先在组件中引入$window服务 在上面加上关键的这一句 elm.css('height', $window.innerHeight + 'px'); 我们可以从$window.innerHeight获取设备的高度,然后把高度加在这个这个组件上,这里要注意的是我原本在内链的样式中设置了height的高度是100%,当我们ng-repeat渲染前是无法获取列表的高度的,所以组件让我们在渲染后获取

这里注意的是如果设备时手机的话一定要加上这句话才能准确获取高度 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=no">

这里写图片描述

下面这句话等价,均可在组件里面执行loadMore函数

//scope.$apply(attr.whenScrolled); //执行 loadMore函数
scope.$apply(scope.loadMore)
Wscats commented 8 years ago
<!DOCTYPE html>
<html ng-app="wsscat">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=no">
        <title></title>
    </head>
    <script type="text/javascript" src="../js/angular.js"></script>
    <style type="text/css">
        li {
            /*height: 120px;*/
            border-bottom: 1px solid gray;
        }

        #fixed {
            height: 100%;
            overflow: auto;
        }
    </style>

    <body ng-controller="indexCtrl">
        <div id="fixed" when-scrolled="loadMore()">
            <ul>
                <li ng-repeat="item in items">{{item}}</li>
            </ul>
        </div>
    </body>
    <script>
        var app = angular.module('wsscat', []);
        app.controller('indexCtrl', function($scope) {
            $scope.items = ['wsscat number'];
            //产生随机数组
            for(var i = 0; i <= 50; i++) {
                $scope.items.push(Math.random() * 10);
            }
            console.log($scope.items);
            $scope.loadMore = function() {
                console.log('下拉刷新更多');
                for(var j = 0; j <= 50; j++) {
                    $scope.items.push(Math.random() * 10);
                }
            }
            console.log($scope);
        })
        app.directive('whenScrolled', function($window) {
            return function(scope, elm, attr) {
                var raw = elm[0];
                elm.css('height', $window.innerHeight + 'px');
                elm.bind('scroll', function() {
                    console.log(raw.scrollTop); //翻滚距离顶部的距离  (一直变动)   
                    console.log(raw.offsetHeight); //未翻滚前列表的高度 (一直固定)
                    console.log(raw.scrollHeight); //列表的加载完的高度 (一直固定)
                    if(raw.scrollTop + raw.offsetHeight >= raw.scrollHeight) {
                        console.log(attr.whenScrolled); //log loadMore()    
                        //scope.$apply(attr.whenScrolled); //执行 loadMore函数
                        scope.$apply(scope.loadMore)
                    }
                });
            };
        });
    </script>

</html>
Wscats commented 8 years ago

利用监听touchstart,touchmove和touchend我们就可以实现下拉刷新

<!DOCTYPE html>
<html ng-app="wsscat">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=no">
        <title></title>
    </head>
    <script type="text/javascript" src="../js/angular.js"></script>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        li {
            /*height: 120px;*/
            border-bottom: 1px solid gray;
        }

        #fixed {
            height: 100%;
            width: 100%;
            overflow: auto;
            position: absolute;
            transition: all 1s;
        }

        .transTop {
            transition: all 1s;
        }
    </style>

    <body ng-controller="indexCtrl">
        <div id="fixed" when-scrolled="loadMore()">
            <ul>
                <li ng-repeat="item in items">{{item}}</li>
            </ul>
        </div>
    </body>
    <script>
        var app = angular.module('wsscat', []);
        app.controller('indexCtrl', function($scope, $timeout) {
            $scope.items = ['wsscat number'];
            //产生随机数组
            for(var i = 0; i <= 50; i++) {
                $scope.items.push(Math.random() * 10);
            }
            console.log($scope.items);
            $scope.loadMore = function(callback) {
                console.log('下拉刷新更多');
                for(var j = 0; j <= 50; j++) {
                    $scope.items.push(Math.random() * 10);
                }
                //console.log(elm);
                $timeout(callback, 1000)

            }
        })
        app.directive('whenScrolled', function($window) {
            return function(scope, elm, attr) {
                var raw = elm[0];
                elm.css('height', $window.innerHeight + 'px');
                elm.bind('scroll', function() {
                    //console.log(raw.scrollTop); //翻滚距离顶部的距离  (一直变动)   
                    //console.log(raw.offsetHeight); //未翻滚前列表的高度 (一直固定)
                    //console.log(raw.scrollHeight); //列表的加载完的高度 (一直固定)
                    if(raw.scrollTop + raw.offsetHeight >= raw.scrollHeight) {
                        console.log(attr.whenScrolled); //log loadMore()    
                        //scope.$apply(attr.whenScrolled); //执行 loadMore函数
                        scope.$apply(scope.loadMore)
                    }
                });
                var touchstart;
                var touchend;
                elm.bind('touchstart', function(data) {
                    touchstart = data.touches[0].pageY;
                })
                elm.bind('touchmove', function(data) {
                    touchend = data.changedTouches[0].pageY;
                    (touchend - touchstart)>0&&(raw.scrollTop==0)?
                    //添加位移和过渡动画
                    elm.addClass('transTop').css('top', (touchend - touchstart) + 'px')
                    :'';
                })
                elm.bind('touchend', function(data) {
                    //往下拉才加载,如果往上则忽略
                    if(touchend - touchstart>0){
                        scope.$apply(scope.loadMore(
                        //传回调函数给控制器中的loadMore函数
                        function() {
                            elm.css('top', '0px')
                        }
                    ))
                    }
                })
            };
        });
    </script>
</html>
Wscats commented 8 years ago

有header时候的下拉刷新

注意如果高度不是全屏的话,刷新框的下拉刷新算法要加上header的距离 raw.scrollTop + raw.offsetHeight + 0.10*$window.innerHeight >= raw.scrollHeight 还要注意的是下拉刷新要绝对定位并且设置属性overflow: auto;,让它出现滚动条

<!DOCTYPE html>
<html ng-app="wsscat">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=no">
        <title></title>
    </head>
    <script type="text/javascript" src="../js/angular.js"></script>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        body{
            height: 100%;
            width: 100%;
        }

        li {
            /*height: 120px;*/
            border-bottom: 1px solid gray;
        }

        #fixed {
            height: 90%;
            width: 100%;
            overflow: auto;
            position: absolute;
            transition: all 1s;
            top:10%
        }

        .transTop {
            transition: all 1s;
        }

        header{
            text-align: center;
            height: 10%;
            width: 100%;
            position: fixed;
            line-height: 400%;
        }
    </style>

    <body ng-controller="indexCtrl">
        <header>下拉刷新</header>
        <div id="fixed" when-scrolled="loadMore()">
            <ul>
                <li ng-repeat="item in items">{{item}}</li>
            </ul>
        </div>
    </body>
    <script>
        var app = angular.module('wsscat', []);
        app.controller('indexCtrl', function($scope, $timeout) {
            $scope.items = ['wsscat number'];
            //产生随机数组
            for(var i = 0; i <= 50; i++) {
                $scope.items.push(Math.random() * 10);
            }
            console.log($scope.items);
            $scope.loadMore = function(callback) {
                console.log('下拉刷新更多');
                for(var j = 0; j <= 50; j++) {
                    $scope.items.push(Math.random() * 10);
                }
                //console.log(elm);
                $timeout(callback, 1000)

            }
        })
        app.directive('whenScrolled', function($window) {
            return function(scope, elm, attr) {
                var raw = elm[0];
                //elm.css('height', $window.innerHeight + 'px');
                elm.bind('scroll', function() {
                    //console.log(raw.offsetHeight); //未翻滚前列表的高度 (一直固定)
                    //console.log(raw.scrollHeight); //列表的加载完的高度 (一直固定)
                    if(raw.scrollTop + raw.offsetHeight + 0.10*$window.innerHeight >= raw.scrollHeight) {
                        console.log(attr.whenScrolled); //log loadMore()    
                        //scope.$apply(attr.whenScrolled); //执行 loadMore函数
                        scope.$apply(scope.loadMore)
                    }
                });
                var touchstart;
                var touchend;
                elm.bind('touchstart', function(data) {
                    touchstart = data.touches[0].pageY;
                })
                elm.bind('touchmove', function(data) {
                    touchend = data.changedTouches[0].pageY;
                    (touchend - touchstart)>0&&(raw.scrollTop==0)?
                    //添加位移和过渡动画
                    elm.addClass('transTop').css('top', (touchend - touchstart) + 'px')
                    :'';
                })
                elm.bind('touchend', function(data) {
                    //往下拉才加载,如果往上则忽略
                    if(touchend - touchstart>0){
                        scope.$apply(scope.loadMore(
                        //传回调函数给控制器中的loadMore函数
                        function() {
                            elm.css('top', '0px')
                        }
                    ))
                    }
                })
            };
        });
    </script>
</html>
Wscats commented 6 years ago

有header时候的下拉刷新

$(document).ready(function () { //ready()文档加载完执行函数
    $(window).scroll(function () {
        var scrollTop = $(this).scrollTop(); //滚动条距离顶部的高度
        var scrollHeight = $(document).height(); //当前页面的总高度
        var windowHeight = $(this).height(); //当前可视的页面高度
        if (scrollTop + windowHeight >= scrollHeight) { //距离顶部+当前高度 >=文档总高度 即代表滑动到底部
            alert("上拉加载,要在这调用啥方法?");
        } else if (scrollTop <= 0) {
            //滚动条距离顶部的高度小于等于0 
            alert("下拉刷新,要在这调用啥方法?");
        }
    });
});