原生js瀑布流布局

用原生js做了个瀑布流布局页面

滚动条到底时会自动创建新div

但出现几个问题

1.第一行的div用的是float:left布局,第二行后通过js改为position:absolute定位,看起来没什么问题,但我想全部用absolute定位,在css中改了position:absolute,html页面就打不开了,为什么后面能绝对定位而第一行却不行

2.创造div的函数中,如果没有滚动条就继续创造div,函数中调用自己,不过现实中在没有滚动条的情况下,有时候执行会继续创造div,有时候却并不执行继续创造,有时候执行了继续创造但滚动条还没出现又停止了,浏览器中亲测条件判断是没问题的

3改变窗口大小时,图片移动会有卡顿现象,有些干脆直接停在半空中,滚轮下就正常了

html代码




    
    
    



    

scss代码 

$bg:#4F000B;
$itemBg1:#9b0637;
$itemBg2:#CE4257;
$itemBg3: #FFC093;
$itemBg4: #FF7F51;

* {
    margin: 0;
    padding: 0
}

.banner {
    height: 20px;
    widows: 100%;
    background: $itemBg4;
    text-align: center
}

#nav {
    text-align: center;
    line-height: 30px;
    background: black;
    height: 30px;
    width: 100%;
    margin: 0;
}

a {
    text-decoration: none;
    color: aliceblue;
}


@mixin setColorAndHover($baseColor) {
    color: $baseColor;

    &:hover {
        background: lighten($baseColor, 10%)
    }
}

@function setCounterBgColor($color) {
    @if (lightness($color)>50) {
        @return darken($color, 50%)
    }

    @else {
        @return lighten($color, 50%)
    }
}

body {
    background: $bg
}

#main {
    position: relative;
    background: $bg;
    counter-reset: item-counter
}


.item {
    box-sizing: border-box;
    padding: 10px;
    float: left;
    transition: 0.5s;
    counter-increment: item-counter;

    &-content {
        position: relative;
        box-sizing: border-box;
        width: 150px;
        background: currentColor;
        font-size: 40px;
        display: flex;
        //justify-content 用于设置或检索弹性盒子元素在主轴(横轴)方向上的对齐方式。
        justify-content: center;
        //align-items 属性定义flex子项在flex容器的当前行的侧轴(纵轴)方向上的对齐方式
        align-items: center;
        @include setColorAndHover($itemBg1);

        &::before {
            position: absolute;
            top: 0;
            left: 0;
            font: 13px bold;
            width: 2em;
            height: 2em;
            line-height: 2em;
            text-align: center;
            background: setCounterBgColor($itemBg1);
            content: counter(item-counter)
        }

        &::after {
            content: 'ಠ‿ಠ';
            color: darken($bg, 30%)
        }

        &-small {
            @include setColorAndHover($itemBg2);

            &::before {
                background: setCounterBgColor($itemBg2)
            }

            &::after {
                content: '♥◡♥'
            }
        }

        &-medium {
            @include setColorAndHover($itemBg3);

            &::before {
                background: setCounterBgColor($itemBg3);
            }

            &::after {
                content: '◔ᴗ◔'
            }
        }

        &-large {
            @include setColorAndHover($itemBg4);

            &::before {
                background: setCounterBgColor($itemBg4)
            }

            &::after {
                content: 'ಠ_๏'
            }
        }
    }
}

js代码

window.onload = function () {
    createDiv('main')
    waterfall('main', 'item')
    window.onresize = function () {
        waterfall('main', 'item')
    }
    window.onscroll = function () {
        navb()
        create()
    }


    //鼠标滚动到指定位置时导航栏固定在视窗顶部的方法
    function navb() {
        var scrollTop = document.documentElement.scrollTop ||
            document.body.scrollTop
        var nav = document.getElementById('nav')
        if (scrollTop > 20) {
            nav.style.cssText = "position:fixed;top:0;z-index:9999"
        } else {
            nav.style.cssText = "position:static"
        }
    }

    //生成父元素中的指定类名的对象的方法
    function getItemObj(parent, className) {
        var obj = parent.getElementsByTagName('*')
        var arr = []
        for (var i = 0; i < obj.length; i++) {
            if (obj[i].className == className) {
                arr.push(obj[i])
            }
        }
        return arr
    }
    //数组中返回最小值索引的方法
    function getMinHeightIndex(heightArr, minHeight) {
        for (var i in heightArr) {
            if (heightArr[i] == minHeight) {
                return i
            }
        }
    }

    //瀑布流布局方法
    function waterfall(parentId, className) {
        var parent = document.getElementById(parentId)
        var arr = getItemObj(parent, className)
        var itemWidth = arr[0].offsetWidth
        var viewWidth = document.documentElement.clientWidth //浏览器窗口宽度
        var columnNum = Math.floor(viewWidth / itemWidth)
        parent.style.cssText = 'width:' + itemWidth * columnNum + 'px; margin:0 auto'

        var heightArr = [] //列高数组
        for (var i = 0; i < arr.length; i++) {
            var itemHeight = arr[i].offsetHeight
            if (i < columnNum) {
                heightArr[i] = itemHeight
                arr[i].style.left = itemWidth * i + 'px'
                arr[i].style.top = '0'
            } else {
                var minHeight = Math.min.apply(null, heightArr)
                var minIndex = getMinHeightIndex(heightArr, minHeight)
                arr[i].style.position = 'absolute'
                arr[i].style.top = minHeight + 'px'
                arr[i].style.left = arr[minIndex].offsetLeft + 'px'
                heightArr[minIndex] += arr[i].offsetHeight
            }
        }
    }

 
    //数组中随机取值的方法
    function randomItem(arr) {
        var index = Math.floor(Math.random() * arr.length)
        return arr[index]
    }

    //滚轮到底部时增加元素的方法
    function createDiv(parentId) {
        for (var i = 0; i < 20; i++) {
            var main = document.getElementById(parentId)
            var itemDiv = document.createElement('div')
            itemDiv.className = 'item'
            main.appendChild(itemDiv)
            //在itemDiv内再增加div
            var subItemDiv = document.createElement('div')
            var subClassName = ['', 'item-content-small', 'item-content-medium', 'item-content-large']
            subItemDiv.className = 'item-content ' + randomItem(subClassName) //随机赋类
            var subDivHeight = Math.floor(Math.random() * 200 + 100) //随机指定高度100-300
            subItemDiv.style.height = subDivHeight + 'px'
            itemDiv.appendChild(subItemDiv)
        }
        var viewWidth = document.documentElement.clientWidth //网页视窗宽度
        var bodyWidth = window.innerWidth //浏览器视窗宽度
        if (viewWidth == bodyWidth) {
            createDiv(parentId)
        } 
    }

    function create() {
        var viewHight = document.documentElement.clientHeight //网页视窗高度
        var scrollTop = document.documentElement.scrollTop || //滚动条高度
            document.body.scrollTop
        var scrollHeight = document.body.scrollHeight //等同页面总高度
        if (scrollTop + viewHight >= scrollHeight - 10) {
            createDiv('main')
            waterfall('main', 'item')
        }
    }
}

 

你可能感兴趣的:(原生js瀑布流布局)