瀑布流布局插件(慢慢优化中)

原创 yiXiaoWang 随笔 js方法总结 2214阅读 2015-07-29 18:29:36 举报

PS:刚开始练习插件开发中,做一个笔记而已,勿喷

只需要传入容器的id和img盒子的className和url即可,数据请求部分使用的是jsonp,所以引用了jQuery库

html + css示例代码

[code]<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="js/jquery.js"/></script>
<script type="text/javascript" src="js/waterfall.js"/></script>
<title></title>
<style type="text/css">
body{
overflow-y: scroll;
}
.box{
padding: 15px 0 0 15px;
}
.pic{
padding: 10px;
border:1px solid #ccc;
box-shadow: 0 0 6px #ccc;
border-radius: 5px;
}
</style>
</head>
<body>
<div id="main">
</div>
</body>
</html>[/code]

waterfall.js

[code]window.onload = function(){

var waterfallObj = new Waterfall({
    containerId: 'main',      //外层容器的id
    containImgClassName: 'box',     //图片盒子的class
    imgWidth: 162,       //图片宽度
    url: 'http://api.xiaohua.360.cn/Baoxiao/listData?callback=__callback&tag=&page=1',      //数据url
    firstRender: 50,      //首次渲染图片数量
    onceLoadNum: 40,     //一次加载出来的图片数量
    maxImgNum: 400     //最多加载的图片数量
});

}

function Waterfall(options){

    /*配置*/
this.contain       = document.getElementById(options.containerId);
this.containImgBox = this.contain.getElementsByClassName(options.containImgClassName);
this.imgWidth      = options.imgWidth || 162;
this.url           = options.url;
this.firstRender   = options.firstRender || 50;
this.onceLoadNum   = options.onceLoadNum || 40;
this.maxImgNum     = options.maxImgNum || 400;

if(!this.contain){
    return false;
}
else{
    this.firstRenderHtml();     //首次渲染页面
this.init();     
}  

}

Waterfall.prototype = {

init: function(){

    var _this = this,
        heightArr = [],
        img = this.contain.getElementsByTagName('img');

    this.contain.style.position = "relative";
    this.contain.style.margin   = "auto";

    for( var i = 0, len = this.containImgBox.length; i < len; i++){

        img[i].style.width = this.imgWidth + 'px';
        this.containImgBox[i].style.position = "";
        this.containImgBox[i].style.float = "left";

        if( i < this.countColNum()){

            heightArr[i] = this.containImgBox[i].offsetHeight;
        }

        else{
            var minHeight = Math.min.apply(null, heightArr);
            var index = getMinheightIndex(minHeight, heightArr);

            this.containImgBox[i].style.position = "absolute"
            this.containImgBox[i].style.top  = minHeight + 'px';
            this.containImgBox[i].style.left = this.containImgBox[index].offsetLeft + 'px';
            heightArr[index] += this.containImgBox[i].offsetHeight;
        }

    }

    this.resize();
    this.scrollLoad();
},

/通过屏幕宽度计算最多能容纳的列数/
countColNum: function (){

    var clientW = document.documentElement.clientWidth,
        offsetW = this.containImgBox[0].offsetWidth,
        containCol = Math.floor(clientW / offsetW);

    this.contain.style.width = offsetW * containCol + 'px';

    return containCol;
},

firstRenderHtml: function(){
    this.getContent();
},

/窗口缩放列数自适应/
resize: function(){

    var self = this;

    window.onresize = function(){
        self.init();
    };
},

/*判断滚动位置,添加数据*/
scrollLoad: function(){

    var _this = this;

    window.onscroll = function(){

        if( _this.judgeScrollLoad() ){

            _this.getContent();
        }
    }

},

judgeScrollLoad: function (){
    var lastBoxTop = this.containImgBox[this.containImgBox.length -1 ].offsetTop + Math.floor(this.containImgBox[this.containImgBox.length -1 ].offsetHeight / 2), 
        scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
        documentH = document.documentElement.clientHeight || document.body.clientHeight;

    if(lastBoxTop < scrollTop + documentH){
        return true;
    }
    else{
        return false;
    }
},
/*加载数据*/
getContent: function () {

    var _this = this;

    $.ajax({
        type : "get",
        async: false,
        url: _this.url,
        dataType : "jsonp",
        jsonp: "callbackparam",
        jsonpCallback:"__callback",
        success : function(res){
            _this.renderHtmlFn(res);
            _this.init();
        }
    });
},

/*渲染页面*/
renderHtmlFn: function (res){
    var html = "";
    for(var i = 0; i < this.onceLoadNum; i++){
        if($(this.contain).find("img").length >= this.maxImgNum){
            return;
        }
        html = '<div class="box"><div class="pic"><img src="'+ res.content_list[i].pic + '"/></div></div>'
        this.contain.innerHTML += html;
    }

}

};

/得到最短高度的索引值/
function getMinheightIndex(value, arr){
if( arr.length == 0){
return;
}
for( var i = 0, len = arr.length; i < len; i++){
if( value == arr[i])
return i;
}
}[/code]

评论 ( 10 )
最新评论
yiXiaoWang 3F 2015-07-30 18:30:31 10F

因为本来就不复杂呀。用jsonp是因为请求数据是跨域请求呀

U_can 3F 2015-07-30 16:47:54 9F

我竟然全都看懂了,但是jsonp: "callbackparam", jsonpCallback:"__callback",这个地方是什么意思呀?为什么数据类型是jsonp,不应该是json吗?

fuier 3F 2015-07-30 09:55:53 8F

我js都不会,没资格啊

fuier 3F 2015-07-30 09:55:52 7F

我js都不会,没资格啊

yiXiaoWang 3F 2015-07-30 09:49:10 6F

可以了吗?我把我测试的html也贴出来了,不好的地方可以指正出来我修改,谢谢

fuier 3F 2015-07-30 08:55:43 5F

  

yiXiaoWang 3F 2015-07-29 23:15:44 4F

还要引入jQuery库的哦

fuier 1F 2015-07-29 23:14:14 3F

不能运行

yiXiaoWang 1F 2015-07-29 23:11:03 2F

你是说注释写的少吗?

yalishizhude 2015-07-29 22:34:18 1F

晕,全是代码啊。。。。