图片瀑布流+懒加载+无限下滑

图片瀑布流+懒加载+无限下滑

import React, { lazy, useEffect, useRef, useState } from 'react';
import styles from './index.less';
import InfiniteScroll from 'react-infinite-scroller';
import Macy from 'macy';
import LazyLoad from 'react-lazy-load';
import { useSetState } from 'react-use';
import { convert } from '@/utils';
import { useDispatch, useRequest, useSelector } from 'umi';

import { Spin } from 'antd';
import { post } from '@/utils/request';

interface EmptyProps {
  imgWidth?: number;
  innerWidth?: number;
  container?: string;
  Conmpont?: any;
  conHeight?: string;
  handlePic?: void;
  overPic?: any;
  overPicfooter?: any;
  margindis?: Object;
  columns?: number;
}

const PicMacy: React.FC<EmptyProps> = (props) => {
  const {
    imgWidth = 360,
    innerWidth,
    container = 'mainList',
    children,
    conHeight = 'calc(100vh - 68px)',
    overPic = () => {},
    overPicfooter = () => {},
    handlePic = (val: object) => {},
    margindis = { left: 16, top: 16 },
    columns = 6,
  } = props;
  const { userInfo } = useSelector((app) => app.user);

  const postqueryPicByLabelOrNot = (data) =>
    post('PortalPic/queryPicByLabelOrNot', data);

  const [scroller, setScroller] = useState({ isLastPage: false });
  const pageNum = useRef(1);
  const hasMore = useRef(true);

  //   const imgList = useRef([]);

  const [imgList, setImgList] = useState([]);
  const postqueryPicByLabelOrNotRequest = useRequest(postqueryPicByLabelOrNot, {
    manual: true,
    onSuccess: (data) => {
      if (data.list.length > 0) {
        pageNum.current = pageNum.current + 1;
        hasMore.current = true;
        setScroller(data);
        setImgList([...imgList, ...data?.list]);
        getMacy();
      }
    },
  });

  let masonry: any = null;
  const getMacy = () => {
    if (masonry) {
      masonry.reInit();
    } else {
      masonry = new Macy({
        container: `#${container}`, // 图像列表容器id
        trueOrder: false, // 不设置的话会顺序会乱
        waitForImages: false,
        useOwnImageLoader: false,
        debug: true,

        //设计间距

        //设置列数
        columns: columns,
        margin: { x: margindis.left, y: margindis.top },
      });
    }
  };

  useEffect(() => {
    lazyload();
  }, [imgList]);
  const lazyload = () => {
    // 创建 IntersectionObserver 实例
    const ob = new IntersectionObserver(
      (entries) => {
        for (let entry of entries) {
          if (entry.isIntersecting) {
            const img = entry.target;
            img.src = img.dataset.src; // 将 data-src 的值赋给 src,实现图片加载
            ob.unobserve(img);
            getMacy();
          }
        }
      },
      {
        root: null, // 相对于整个视口进行判断
        rootMargin: '0px 0px 100px 0px', // 元素进入视口一段距离即触发
        threshold: [0, 0.1], // 元素完全进入视口时触发
      },
    );
    // 获取所有带有 data-src 属性的图片元素
    const imgs = document.querySelectorAll('img[data-src]');
    // 遍历图片元素,将每个元素绑定到 IntersectionObserver 上进行观察
    imgs.forEach((item) => {
      ob.observe(item);
    });
    // const additionalImgs = document.querySelectorAll(
    //   'img[data-src-additional]',
    // );
    // additionalImgs.forEach((item, index) => {
    //   if (index < 30) {
    //     item.src = item.dataset.srcAdditional;
    //   }
    // });
  };

  const getMore = () => {
    hasMore.current = false;
    if (userInfo.userId && !scroller.isLastPage) {
      postqueryPicByLabelOrNotRequest.run({
        currentPage: pageNum.current,
        userId: '1722523689024618496',
        pageSize: 50,
      });
    }

    // getMacy();
  };
  useEffect(() => {
    if (userInfo.userId) {
      getMore();
    }
  }, [userInfo]);

  return (
    <div className={styles.PicMacyLayout} style={{ height: conHeight }}>
      {children}

      <InfiniteScroll
        className="list-contents"
        initialLoad={true}
        pageStart={1} //首页为1,可根据自己的具体需求
        loadMore={async () => await getMore()}
        loader={
          !scroller.isLastPage && (
            <div style={{ textAlign: 'center' }}>
              <Spin spinning={true}></Spin>
            </div>
          )
        }
        useWindow={false} //****将滚动侦听器添加到窗口,或者添加组件的parentNode****
        hasMore={hasMore.current}
      >
        <div className={styles.recomandList} id={container} ref={scroll}>
          {imgList?.map((item, index) => {
            return (
              <div className={styles.item_box}>
                <div className={styles.recomandItem} key={index}>
                  <img
                    src={
                      'https://img0.baidu.com/it/u=1035818712,4106770352&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800'
                    }
                    className={styles.item_img}
                    data-src={item.pictureUrl}
                    style={{ width: `${convert(imgWidth)}` }}
                    onClick={() => handlePic(item)}
                  />

                  <div className={styles.overpic}>{overPic(item)}</div>
                  <div className={styles.overpic_footer}>
                    {overPicfooter(item)}
                  </div>
                </div>
              </div>
            );
          })}
        </div>
        {scroller.isLastPage && (
          <div style={{ textAlign: 'center' }}>到底啦~</div>
        )}
      </InfiniteScroll>
    </div>
  );
};

export default PicMacy;

@import '../../assets/util.less';

.PicMacyLayout {
  overflow: auto;
  //   padding: 0 25px;
  .recomandItem {
    position: relative;

    .overpic {
      position: absolute;
      top: 0px;
      visibility: hidden;
    }
    .overpic_footer {
      position: absolute;
      bottom: 0px;
      visibility: hidden;
    }
  }
  .item_img {
    background: linear-gradient(0deg, #000000 0%, rgba(0, 0, 0, 0.43) 72%);
    border-radius: 14px;
  }
  .recomandItem:hover {
    .overpic {
      visibility: visible;
    }
    .overpic_footer {
      visibility: visible;
    }

    cursor: pointer;
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 下面是一个基于 jQuery 的下拉瀑布和 Mustache 模板的示例代码: HTML 部分: ```html <div id="content"></div> <div id="loading">Loading...</div> ``` CSS 部分: ```css #content { column-count: 3; column-gap: 10px; } .item { break-inside: avoid-column; margin-bottom: 10px; } img { width: 100%; } #loading { display: none; text-align: center; font-size: 20px; color: #999; margin-top: 20px; } ``` JS 部分: ```javascript $(function() { var page = 1; var isLoading = false; var isEnd = false; function loadData() { if (isLoading || isEnd) { return; } isLoading = true; $('#loading').show(); $.ajax({ url: 'data.php', type: 'get', data: { page: page }, dataType: 'json', success: function(data) { if (data.length > 0) { var template = $('#template').html(); Mustache.parse(template); var rendered = Mustache.render(template, data); $('#content').append(rendered); page++; } else { isEnd = true; } }, complete: function() { isLoading = false; $('#loading').hide(); } }); } $(window).scroll(function() { var scrollTop = $(this).scrollTop(); var windowHeight = $(this).height(); var contentHeight = $('#content').height(); if (scrollTop + windowHeight >= contentHeight && contentHeight > 0) { loadData(); } }); loadData(); }); ``` 其中,data.php 是一个返回 JSON 数据的后端接口,返回数据格式如下: ```json [ { "id": 1, "title": "item 1", "image": "image1.jpg" }, { "id": 2, "title": "item 2", "image": "image2.jpg" }, ... ] ``` Mustache 模板部分: ```html <script id="template" type="x-tmpl-mustache"> {{#items}} <div class="item"> <h2>{{title}}</h2> <img src="{{image}}" alt=""> </div> {{/items}} </script> ``` 以上代码实现了一个基本的下拉瀑布和 Mustache 模板的示例,你可以根据自己的需求进行修改和扩展。 ### 回答2: jQuery是一种行的JavaScript库,用于简化HTML文档遍历、事件处理、动画效果和AJAX等操作。下拉是一种网页方式,在用户滚动到页面底部时,通过发送请求更多内容。瀑布是一种多列布局方式,类似于瀑布动,每一列按照内容的高度自动调整位置。 jQuery可以很方便地实现下拉功能。通过监听窗口的滚动事件,当滚动到页面底部时,发送请求获取更多数据,然后将数据添到页面中。这样,用户就可以在滚动页面的过程中无缝地更多内容,提升用户体验。 瀑布布局通常使用CSS和JavaScript来实现。在jQuery中,可以使用瀑布插件如"Masonry"或"Isotope"来实现瀑布布局。这些插件可以根据内容的大小和位置自动调整各个元素的位置,从而实现瀑布效果。 Mustache是一种轻量级的模板引擎,可以将数据和HTML模板进行结合,生成动态的网页内容。在使用jQuery进行下拉瀑布布局时,Mustache可以用于将获取到的数据与指定的HTML模板进行结合,生成可展示的内容。 通过结合使用jQuery、下拉瀑布布局和Mustache,我们可以实现一个功能强大且用户友好的网页。用户可以通过滚动页面来更多内容,而不需要手动点击按钮。的内容可以利用瀑布布局自动调整位置,使页面更美观。而Mustache可以将获取到的数据动态地呈现在指定的HTML模板中,实现内容的动态更新。 总之,jQuery下拉瀑布布局和Mustache模板引擎的结合,可以让我们更便捷地实现前端开发中对于网页和布局的需求。 ### 回答3: jQuery下拉瀑布和Mustache都是常用的前端技术。 jQuery是一款优秀的JavaScript库,可以简化HTML文档的遍历、事件处理、动画效果等操作。在下拉中,可以利用jQuery监听用户滚动事件,当滚动到特定位置时触发新数据的操作。通过Ajax请求获取数据,再通过jQuery插入到页面中,实现无刷新的数据瀑布是一种网页布局方式,类似于瀑布的形态,每一块内容依次排列,高度不一,但是整体效果呈现出自然的瀑布效果。在实现瀑布布局时,可以借助jQuery的animate()函数来设置元素的位置和动画效果,为页面元素创建瀑布布局。 Mustache是一种轻量级的逻辑-less模板引擎,用于渲染模板数据到HTML文档。通过Mustache的语法标签,我们可以在HTML代码中插入占位符,然后再通过jQuery获取到数据,将数据和模板结合,最终生成动态内容,并插入到页面中。 综上所述,使用jQuery下拉瀑布和Mustache可以实现在网页中实现下拉新数据的功能,并使用瀑布布局展示数据,最后通过Mustache模板引擎渲染数据到页面中。这样能够提升用户体验和页面的可视性,实现更畅的数据展示。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值