美文网首页
jquery 无限加载+Jasonp+瀑布流

jquery 无限加载+Jasonp+瀑布流

作者: 黑色的五叶草 | 来源:发表于2018-05-09 09:47 被阅读0次

写法一:对象写法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>瀑布流+懒加载+jasonp —— 思路1</title>
    <script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js"></script>
    <style>
        html, body, ul, li, p {
            margin: 0;
            padding: 0;
        }

        ul, li {
            list-style: none;
        }

        .ct {
            position: relative;
            padding: 10px;
            margin: 0 auto;
        }
        
        .clearfix:after {
            content: '';
            display: block;
            clear: both;
        }

        .ct .item {
            background: #fff;
            width: 200px;
            position: absolute;
            padding: 0 0 10px 0;
            box-shadow: 2px 2px 2px #E8E8E8, -2px -2px 2px #E8E8E8;
            border: 1px solid #DFDFDF;
            margin: 10px;
            transition: all 1s;
        }

        .ct .item a {
            display: block;
        }
        .ct .item img {
            /* margin: 12px;
            width: 176px; */
            display: block;
            width: 100%;
            box-sizing: border-box;
            padding: 10px;
        }

        .ct .item .header {
            padding-bottom: 10px;
            margin: 0 12px;
            border-bottom: 1px solid #DBDBDB;
        }

        .ct .desp {
            font-size:12px;
            line-height: 1.8;
            margin: 10px 15px 0;
            color: #777371;
        }

        #load {
            visibility: hidden;
        }
    </style>
</head>
<body>
    <div class="ct-waterfall">
        <ul id="pic-ct" class="ct clearfix">
            <!-- <li class="item">
                <a href="#" class="link">
                    <img src="" alt="">
                </a>
                <h4 class="header"></h4>
                <p class="desp"></p>
            </li> -->
        </ul>
        <div id="load">隐藏标记位</div>
    </div>


    <script>
/*        
        var Exposure = {
            init: function($target, handler){
                this.$c = $(window);
                this.$target = $target;
                this.handler = handler;

                this.bind();
                this.checkShow();
            },
            bind: function(){
                var me = this,
                    clock = null,
                    interval = 100;
                $(window).on('scroll', function(clock){
                    if(clock){
                        clearTimeout(clock);
                    }
                    clock = setTimeout(function(){
                        me.checkShow();
                    }, interval);
                });
            },
            checkShow: function(){
                var me = this;
                this.$target.each(function(){
                    var $cur = $(this);
                    if(me.isShow($cur)){
                        if(me.handler){
                            me.handler.call(this);
                        }
                    }
                });
            },
            isShow: function($el){
                var scrollH = this.$c.scrollTop(),
                    winH = this.$c.height(),
                    top = $el.offset().top;
                if(winH + scrollH > top){
                    return true;
                } else {
                    return false;
                }
            }
        }
*/
        var Exposure = {
            init: function($target, handler){
                this.$target = $target;
                this.handler = handler;
                this.clock = null;

                this.bind();
                this.checkShow();
            },
            bind: function(){
                var that = this;
                $(window).on('scroll', function(){
                    if(that.clock){
                        clearTimeout(that.clock);
                    }
                    that.clock = setTimeout(function(){
                        that.checkShow();
                    }, 300);
                });
            },
            isShow: function(target){
                console.log(1);
                var top = target.offset().top,
                    $winH = $(window).height(),
                    $scrollH = $(window).scrollTop;
                console.log(top, $winH, $scrollH);
                if(top < $winH + $scrollH){
                    return true;
                } else {
                    return false;
                }
            },
            checkShow: function(){
                console.log(1);
                if(this.isShow(this.$target)){
                    this.handler();
                }
            }
        }

        var waterFall = {
            // arrHeight: [],
            init: function($ct){
                this.$ct = $ct;
                this.arrHeight = [];

                this.bind();
                this.start();
            },
            bind: function(){
                var me = this;
                $(window).on('resize', function(){
                    me.start();
                });
            },
            start: function($nodes){
                var me = this;
                this.$items = this.$ct.find('.item');
                if(this.$items.length === 0) return;
                this.$ctWidth = this.$ct.width();
                console.log(this.$ctWidth);
                this.itemWidth = this.$items.outerWidth(true);
                this.colNum = Math.floor(this.$ctWidth / this.itemWidth);
                this.$ct.width(this.itemWidth * this.colNum);
                console.log(this.$ct.width());
                console.log(this.itemWidth);
                console.log(this.colNum);

                if(this.arrHeight.length === 0 || !$nodes){
                    this.arrHeight = [];
                    for(var i=0; i<this.colNum; i++){
                        this.arrHeight[i] = 0;
                    }
                }
                if($nodes){
                    console.log(this.arrHeight.length);
                    $nodes.each(function(){
                        var $item = $(this);
                        $item.find('img').load(function(){
                            me.placeItem($item);
                            me.$ct.height(Math.max.apply(this, me.arrHeight));
                        });
                    });
                } else {
                    this.$items.each(function(){
                        var $item = $(this);
                        me.placeItem($item);
                    });
                    console.log(me.arrHeight);
                    me.$ct.height(Math.max.apply(this, me.arrHeight));
                }
            },
            placeItem: function($el){
                var o = this.getIndexOfMin(this.arrHeight),
                    idx = o.idx,
                    min = o.min;
                $el.css({
                    left: this.itemWidth * idx,
                    top: min  //y轴放置最小arr[i]
                });
                // console.log(o, idx, min, this.itemWidth);
                this.arrHeight[idx] += $el.outerHeight(true);
            },
            getIndexOfMin: function(arr){
                var idx = 0,
                    min = arr[0];
                for(var i=0; i<arr.length; i++){
                    if(arr[i] < min){
                        idx = i;
                        min = arr[i];
                    }
                }
                return {
                    idx: idx,
                    min: min
                };
            }
        }

        var lock = false, 
            page = 1,
            pageCount = 30;


        function getData(callback){
            console.log(page);
            if(lock){
                return; //起始状态为false,所以不会执行if语句
            }
            lock = true;  //上锁,禁止滚动
            $.ajax({
                url: 'http://platform.sina.com.cn/slide/album_tech',
                type: 'get',
                dataType: 'jsonp',
                jsonp: 'jsoncallback',
                data: {
                    app_key: '1271687855',
                    format: 'json',
                    size: 'img',
                    page: page,
                    num: pageCount
                },
                success: function(ret){
                    console.log(ret);
                    lock = false;  //请求到数据,此时解锁变为可以滚动
                    if(ret.status.code == 0){
                        callback(ret.data);
                        page++;
                        console.log(page);
                    }
                },
                error: function(){
                    lock = false;  //发生错误是,变为解锁状态可以滚动,可以继续执行请求数据
                }
            });
        }
        /*一开始是false  所以return不跳出,
        给lock设置为true,这时候发送请求,请求返回结果之前,
        lock一直都是true 所以这时候你要是往死里划,一直都是跳出函数
        当请求成功了,lock设置为false,这时候一切和一开始一样了,可以继续发请求了*/
        function renderData(items){
            var $nodes,
                im = '';
            for(var i=0; i<items.length; i++){
                im += '<li class="item">';
                im += ' <a href="#" class="link"><img src="' + items[i].img_url + '"alt=""></a>';
                im += ' <h4 class="header">' + items[i].short_name + '</h4>';
                im += ' <p class="desp">' + items[i].short_intro + '</p>';
                im += '</li>';
            }
            $nodes = $(im);
            $('#pic-ct').append($nodes);
            return $nodes;
            console.log($nodes);
        }


        $(function(){
            waterFall.init($('#pic-ct'));
            Exposure.init($('#load'), function(){
                getData(function(data){
                    console.log(1);
                    var $nodes = renderData(data);
                    waterFall.start($nodes);
                    console.log(1);
                });
            });
        });

    </script>
</body>
</html>

写法二:原型写法

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>瀑布流+懒加载+jasonp —— 思路2</title>
    <style type="text/css">
        html,
        body,
        ul,
        li,
        p,
        div {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        ul,
        li {
            list-style: none;
        }

        a {
            text-decoration: none;
        }

        .clearfix:after {
            content: '';
            clear: both;
            display: block;
        }

        .wrap {
            width: 900px;
            margin: 0 auto;
        }

        .pic-ct {
            position: relative;
        }

        .pic-ct .item {
            position: absolute;
            padding-bottom: 10px;
            width: 280px;
            margin: 10px;
            border: 1px solid #eee;
            opacity: 0;
            transition: all 0.8s;
        }

        .pic-ct .item img {
            margin: 10px;
            width: 260px;
        }

        .pic-ct .item .header {
            margin: 0 12px;
            height: 25px;
            border-bottom: 1px solid #eee;
        }

        .pic-ct .item .des {
            margin: 10px 15px 0;
            color: #333;
            font-size: 12px;
            line-height: 1.8;
        }

        .btn {
            display: inline-block;
            visibility: hidden;
            padding: 20px 40px;
            border-radius: 3px;
            font-size: 18px;
            font-weight: bold;
            background: #fed136;
            cursor: pointer;
        }

        .hide {
            display: none;
        }
    </style>
</head>

<body>
    <div class="wrap">
        <ul class="pic-ct clearfix">
            <!-- <li class="item hide"></li> -->
        </ul>
        <div id="load" class="btn">Load More</div>
    </div>
    <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script>
        function Addmore($node) {
            console.log(this)
            this.getData();
            this.click($node);
            this.perPageCount = 9;
            this.curPage = 1;
            this.clock = null;

            this.list = $node.find('.pic-ct');
        }

        Addmore.prototype = {
            getData: function () {
                var that = this;
                $.ajax({
                    url: 'http://platform.sina.com.cn/slide/album_tech',
                    dataType: 'jsonp', //这里使用了新浪新闻的 jsonp 接口,大家可以直接看数据, 如: http://platform.sina.com.cn/slide/album_tech?jsoncallback=func&app_key=1271687855&num=3&page=4
                    jsonp: "jsoncallback",
                    data: {
                        app_key: '1271687855',
                        num: this.perPageCount,
                        page: this.curPage
                    }
                }).done(function (ret) {
                    console.log(ret);
                    that.place(ret);
                    that.curPage++;
                }).fail(function () {
                    alert('获取数据失败');
                });
            },
            checkShow: function() {
                if(this.isShow($('#load'))) {
                    console.log(1);
                    this.getData();
                }
            },
            click: function ($node) {
                var that = this;
                $(window).on('scroll', function () {
                    if(that.clock){
                        clearTimeout(that.clock);
                    }
                    that.clock = setTimeout(function(){
                        that.checkShow();
                    }, 300);
                });
            },
            isShow: function ($el) {

                var scrollH = $(window).scrollTop(),
                    winH = $(window).height(),
                    top = $el.offset().top;

                if (top < winH + scrollH) {
                    return true;
                } else {
                    return false;
                }
            },
            renderData: function (res) {
                var str = '';
                for (var i = 0; i < res.data.length; i++) {
                    str += '<li class="item">';
                    str += '  <a class="portfolio-link" href="javascript:void(0)">';
                    str += '   <div class="portfolio-hover"><i class="fa fa-plus"></i></div>';
                    str += '   <img src="' + res.data[i].img_url + '" alt="roundicons">';
                    str += '  </a>';
                    str += '  <div class="portfolio-desp">';
                    str += '  <h3>' + res.data[i].short_name + '</h3>';
                    str += '  <p class="text-muted">' + res.data[i].short_intro + '</p>';
                    str += '  </div>';
                    str += '</li>';
                }
                // console.log(str);
                var $nodes = $(str);
                this.list.append($nodes);
                return $nodes;
            },          
            //延迟组件。让页面代码同时渲染
            place: function (ret) {
                console.log(ret);
                var $nodes = this.renderData(ret),
                    deferreds = [];
                $nodes.find('img').each(function () {
                    var defer = $.Deferred();
                    $(this).on('load', function () {
                        defer.resolve();  //deferred.resolve():解决Deferred(延迟)对象,并根据给定的args参数调用任何完成回调函数(doneCallbacks)
                    });
                    deferreds.push(defer);
                });
                $.when.apply(null, deferreds).done(function () {  //jQuery.when():提供一种方法来执行一个或多个对象的回调函数, Deferred(延迟)对象通常表示异步事件。
                    new Waterfall($('.wrap'));
                });
            }
        };


        function Waterfall($node) {
            this.$node = $node;
            this.init();
        }
        
        Waterfall.prototype = {
            init: function () {
                this.render(this.$node);
                this.bind(this.$node);
            },
            bind: function ($node) {
                var that = this;
                $(window).on('resize', function () {
                    that.render($node);
                });
            },
            render: function ($node) {
                var ctWidth = $node.find('.pic-ct').width();
                var $item = $node.find('.pic-ct li');
                var itemWidth = $item.outerWidth(true);
                var colNum = parseInt(ctWidth / itemWidth);
                var colSumHeight = [];
                for (var i = 0; i < colNum; i++) {
                    colSumHeight.push(0);
                }
                $item.each(function () {
                    var $cur = $(this);
                    var idx = 0,
                        minSumHeight = colSumHeight[idx];
                    for (var j = 0; j < colSumHeight.length; j++) {
                        if (colSumHeight[j] < minSumHeight) {
                            idx = j;
                            minSumHeight = colSumHeight[idx];
                        }
                    }
                    $cur.css({
                        top: minSumHeight,
                        left: itemWidth * idx,
                        opacity: 1
                    });
                    colSumHeight[idx] += $cur.outerHeight(true);
                });
                $node.find('.pic-ct').css({
                    height: Math.max.apply(null, colSumHeight)
                });
            }
        };

        new Addmore($('.wrap'));
    </script>
</body>

</html>

相关文章

  • jquery 无限加载+Jasonp+瀑布流

    写法一:对象写法 写法二:原型写法

  • 无限加载瀑布流

  • jQuery瀑布流插件masonry使用教程

    瀑布流特别适合多图片布局加载,效果很理想。 masonry是基于jquery的瀑布流插件,简单实用,本文就以滑动无...

  • Jquery 瀑布流(滚动加载)

    源码下载地址 实现思路 通过容器宽度 和每列的宽度 可以计算出列数。 数组来保存每一列的高度,当页面加载新的盒子时...

  • 瀑布流

    瀑布流jQuery瀑布流插件 Masonry:http://www.jq22.com/jquery-info362...

  • 32.jquery 实战-无限加载+jsonp+瀑布流

    代码 准备工作在图片容器底部底部放一个元素#load,visiablity:hidden,让用户不可见。在图片容器...

  • 基于 jquery.nicescroll 实现瀑布流

    起因 PC端中大量使用 jquery.nicescroll 滚动条,现需实现列表瀑布流加载 实现过程 1、查看 A...

  • 9-5bug处理

    关于RecyleView瀑布流滑动加载数据,顶部出现空白。 关于RecyleView瀑布流显示加载图片乱跳 下拉刷...

  • jquery 瀑布流

    瀑布流布局的特点: 【1】展示的图片元素都是等宽不等高,图片的位置用position:absolute定位来摆放。...

  • jQuery 瀑布流

    瀑布流的实现原理 要想实现瀑布流首先需要确定需要排列的内容,宽度需要一致; 设定父容器相对定位,需排列子元素绝对定...

网友评论

      本文标题:jquery 无限加载+Jasonp+瀑布流

      本文链接:https://www.haomeiwen.com/subject/ykgukftx.html