ionic -angular 瀑布流

html

 <!-- 瀑布流方式-->
    <div id="container" [ngClass]="list.length>0?'show':'hide'">
        <div class="box" *ngFor="let item of list" (click)="goDetail(item)">
            <div class="box_img">
                <img src="assets/img/IMG_20190921_174133.jpg" class="im">
                <ion-badge slot="start" *ngIf="item.status" class="badge">已标识</ion-badge>
                <ion-badge slot="start" *ngIf="!item.status" class="badge">未标识</ion-badge>
                <div style="margin: 4px 2px; text-align:center;font-size: 13px; color: #368ab5;">
                    <div style="width: 32%;display:inline-block;"><label class="titlecs">品类数</label></div>
                    <div style="width: 32%;display:inline-block;"><label class="titlecs">店家数</label></div>
                    <div style="width: 32%;display:inline-block;"><label class="titlecs">品牌数</label></div>
                </div>
                <div style="margin: 4px 2px;padding-bottom: 2px; text-align:center;font-size: 14px; color: #917d5b;">
                    <label style="display:inline-block; width: 32%;text-align: center; ">{{item.caseNum}}</label>
                    <label style="display:inline-block;width: 32%; text-align: center; ">{{item.shopkeeperNum}}</label>
                    <label style="display:inline-block;width: 32%; text-align: center; ">{{item.brandNum}}</label>
                </div>
            </div>
        </div>
    </div>
    <ion-infinite-scroll (ionInfinite)="doInfinite($event)">
        <ion-infinite-scroll-content loadingSpinner="bubbles " style="color: black;" [loadingText]="loadText" position="bottom ">
        </ion-infinite-scroll-content>
    </ion-infinite-scroll>

    <!-- 骨架框-->
    <div>
        <div id="containerSke" [ngClass]="loading && list.length==0?'show':'hide'">
            <div class="box" *ngFor="let i of [160,186,175,170,160,180,165]">
                <div class="box_img">
                    <div style="width: 94%;display: inline-block; margin: 8px;">
                        <ion-skeleton-text [animated]="true" [style]="'height:'+i+'px;border-radius: 3px;'"></ion-skeleton-text>
                    </div>
                    <div style="margin: 6px 6px;padding-bottom: 2px; text-align:center;font-size: 13px; color: #917d5b;">
                        <label><ion-skeleton-text [animated]="true" style="width: 100%; height: 16px; margin-bottom: 8px;border-radius: 3px;"></ion-skeleton-text></label>
                        <label><ion-skeleton-text [animated]="true" style="display:block;width: 88%;margin-bottom: 8px;height: 16px;border-radius: 3px;"></ion-skeleton-text></label>
                    </div>
                </div>
            </div>
        </div>
    </div>

css

// 瀑布流 样式
#container {
    position: relative;
    display: inline-block;
}

#containerSke {
    position: relative;
    display: inline-block;
}

.box {
    padding: 4px;
    float: left;
    margin: 0 auto;
}

.box_img {
    width: 177.5px;
    border: 1px solid #cccccc;
    box-shadow: 0 0 5px #ccc;
    // border-radius: 10px;
    position: relative;
}

.box_img>img {
    width: 100%;
    height: auto;
    overflow: hidden;
    // border-radius: 8px 8px 0 0;
}

ion-infinite-scroll {
    width: 100%;
    position: fixed;
    z-index: 99;
    bottom: 0;
}

.titlecs {
    display: inline-block;
    // width: 32%;
    text-align: center;
    background-color: #b3ddf3;
    border-radius: 3px;
    padding: 0px 3px;
}

.badge {
    position: absolute;
    top: 0px;
    left: 0px;
    padding: 6px 10px;
    font-size: 14px;
    --background: #37a484;
    --color: white;
    font-weight: normal;
    border-radius: 0px;
}

.hide {
    visibility: hidden;
}

.show {
    visibility: visible;
}

ts

export class RecordComponent implements OnInit, AfterViewChecked {
  list: any = [];
  loading = false;
  search: string;
  pageSize = 2;//时间个数,2表示2天的数据
  pageIndex = 0;
  skip = 0;
  isEnd = false;
  loadText = '正在加载...';
  timer;
  constructor(
    private router: Router,
    private service: RecordService,
    private alertControll: AlertController,
    private el: ElementRef
  ) { }

  ngAfterViewChecked(): void {
    // let parentNode = document.getElementById("container");
    // this.getNode(parentNode);
  }

  ngOnInit() {
    this.getRecodrds(null);
  }
  //#region 瀑布流
  ionViewWillEnter() {
//加载骨架框 let parentNode
= document.getElementById("containerSke"); this.getNode(parentNode); } getNode(parentNode) { // let parentNode = document.getElementById("container"); if (parentNode != undefined) { let childNodeArray: any = parentNode.getElementsByClassName("box"); let screenWidth = document.documentElement.clientWidth; let boxImg: any = document.querySelectorAll(".box_img"); let loding = document.querySelector("ion-infinite-scroll"); let childWidth = screenWidth / 2; // console.log(`屏幕的宽` + screenWidth) // console.log(`box的宽` + childWidth) let num = Math.floor(screenWidth / childWidth); //获得一排摆的个数 用Math.floor()转换为整数 parentNode.style.cssText = "width:" + childWidth * num + "px; margin:0 auto; height:auto"; //固定container的宽并设置居中 for (var i = 0; i < boxImg.length; i++) { boxImg[i].style.cssText = "width:" + (childWidth - 10) + "px"; } this.setImagePosition(num, childNodeArray); } } setImagePosition(num, childArray) { var imgHeightArray = [];//定义数组用于存放所有图片的高度 for (var i = 0; i < childArray.length; i++) { //遍历所有图片 if (i < num) { imgHeightArray[i] = childArray[i].offsetHeight; //取得第一排图片的高度 } else { var minHeight = Math.min.apply(null, imgHeightArray); //获取存放图片中高度最小的图片 var minIndex = this.getMinHeight(imgHeightArray, minHeight); //函数获得高度最小的图片的位置 childArray[i].style.position = "absolute"; //绝对定位图片 childArray[i].style.top = minHeight + "px"; //图片距顶部像素 childArray[i].style.left = childArray[minIndex].offsetLeft + "px"; //图片距左的像素 imgHeightArray[minIndex] = imgHeightArray[minIndex] + childArray[i].offsetHeight; //将最低高度的box的高度加上它下方(新一个图片)的box高度 } } } /** * 获取等于minHeight值的元素的数组位置index * @param minHeight * @returns */ getMinHeight(imgHeightArray, minHeight) { for (var i in imgHeightArray) { if (imgHeightArray[i] == minHeight) { //循环所有数组的高度 让它等于最小图片的高度 返回i值 return i; } } } /** * 判断图片元素是否加载完成,完成之后再加载瀑布流模式(解决瀑布流图片重叠的问题) */ isImageLoad() { //所有的图片元素 var imgEls = this.el.nativeElement.querySelectorAll('.im'); // 判断所有的图片元素是否加载完成 if (imgEls.length == this.list.length) { //删除定时器 clearTimeout(this.timer); let parentNode = document.getElementById("container"); this.getNode(parentNode); } else { this.timer = setTimeout(() => { this.isImageLoad() }, 100); } } //这里是借助ionic的上拉加载代替网页的滚动监听实现加载更多 doInfinite(infiniteScroll) { this.loadText = '正在加载...'; this.getRecodrds(infiniteScroll); } //#endregion getRecodrds(infiniteScroll) { this.loading = true; this.skip = this.pageIndex * this.pageSize; this.service.getPictureRecords({ skip: this.skip, size: this.pageSize }) .pipe( finalize(() => { this.loading = false; if (infiniteScroll) { if (this.isEnd) { console.log('到底啦') this.loadText = '到底啦'; } infiniteScroll.target.complete(); } }) ) .subscribe(result => { if (result.length > 0) { var datas: any = []; datas = this.list; datas.push(...result); this.list = datas; this.pageIndex++; this.isEnd = false; this.isImageLoad() } else { this.isEnd = true; } }) } }

效果:

骨架框                                                                                结果

 

posted @ 2022-11-09 12:02  流年sugar  阅读(74)  评论(0编辑  收藏  举报