Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

angular下拉刷新 #12

Open
Wscats opened this issue Aug 15, 2016 · 6 comments
Open

angular下拉刷新 #12

Wscats opened this issue Aug 15, 2016 · 6 comments

Comments

@Wscats
Copy link
Owner

Wscats commented Aug 15, 2016

注意这里要固定列表的高度
在组件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
Copy link
Owner Author

Wscats commented Aug 17, 2016

<!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
Copy link
Owner Author

Wscats commented Aug 22, 2016

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

我们根据上面可以继续改进,首先在组件中引入$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
Copy link
Owner Author

Wscats commented Aug 22, 2016

<!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
Copy link
Owner Author

Wscats commented Aug 23, 2016

利用监听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
Copy link
Owner Author

Wscats commented Sep 18, 2016

有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
Copy link
Owner Author

Wscats commented Nov 1, 2018

有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("下拉刷新,要在这调用啥方法?");
        }
    });
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant