前两天看上了一个网友的卡片样式,想着把我的商品页面优化下,然后折腾了2天,重构了页面和功能,做到了美观、完整加载,现在分享给有需要的网友。
前端页面:
<div id="containerpub" class="containerpub row">
<?php if($list){?>
<?php foreach ($list as $v){?>
<div class="item" id="<?php echo $v['id']?>">
<div class="title"><a href="<?php echo site_url('/shop/view/'.$v['id']);?>"><?php echo sb_substr($v['title'],30);?></a></div>
<?php if(!$this->myclass->from_mobile()){?>
<a href="<?php echo site_url('/shop/view/'.$v['id']);?>"><img class="aligncenter" src="<?php echo base_url('plugins/st.php');?>?src=<?php echo base_url('uploads/shop/'.$v['picurl']);?>&h=&w=213&zc=1" alt="<?php echo $v['title'];?>"></a>
<?php } else{?>
<a href="<?php echo site_url('/shop/view/'.$v['id']);?>"><img class="aligncenter" src="<?php echo base_url('plugins/st.php');?>?src=<?php echo base_url('uploads/shop/'.$v['picurl']);?>&w=300&zc=1" alt="<?php echo $v['title'];?>"></a>
<?php }?>
<!-- 简介 -->
<div class="intro">
<?php echo sb_substr(cleanhtml($v['description']),60);?>
</div>
<!-- /简介 -->
<!-- 浏览及评论数量 -->
<div class="opt-info">
<span>库存量 <em><?php echo $v['stock']-$v['sellnum']?></em></span>
<span>折后价 <em><?php echo $v['dprice']?></em></span>
</div>
<!-- /浏览及评论数量 -->
<!-- 评论 -->
<div class="cmt-boxst">
<!-- 一条评论 -->
<div class="cmt-item">
<div class="avatar" data-user-id="<?php echo htmlspecialchars($v['uid']); ?>">
<a href="<?php echo site_url('shop/open/' . htmlspecialchars($v['uid'])); ?>" class="toboxs">
<?php if ($v['avatar']): ?>
<img alt="<?php echo htmlspecialchars($v['username']); ?>" class="medium_avatar" src="<?php echo base_url(htmlspecialchars($v['avatar'])); ?>" onerror="noface();" />
<?php else: ?>
<img alt="<?php echo htmlspecialchars($v['username']); ?>" class="medium_avatar" src="/uploads/avatar/default.jpg" />
<?php endif; ?>
</a>
</div>
<div class="comment-hd">
<span class="username"><?php echo htmlspecialchars($v['username']); ?></span><br>
<time><?php echo $this->myclass->friendly_date($v['time']); ?> 发布</time>
</div>
</div>
</div>
</div>
<?php }}?>
</div>
</div>
</div>
<div id="loading" class="loading-box" style="display:none;">
<span class="loading">拼命加载中,请稍后...</span>
</div>
控制器里面:
public function photogetmore($id)
{
$data['view_url']=array_keys($this->router->routes,'shop/view/$1');
$data['flist_url']=array_keys($this->router->routes,'shop/flist/$1');
$nums=rand(5,8);
$data['list'] = $this->shop_m->get_goods_list_photonopagest($id,$nums);
header('Content-Type: application/json');
echo json_encode($data['list']);
}
这个主要是从模型中获取:小于最近加载item卡片的ID值,从数据库查询小于该ID的的内容(倒叙)
模型:
public function get_goods_list_photonopagest ($id,$limit)
{
$this->db->select('shop_list.*,b.username, b.avatar, d.cname');
$this->db->from('shop_list');
$this->db->join('users b','b.uid = shop_list.uid','left');
$this->db->join('shop_categories d','d.cid = shop_list.cid','left');
$this->db->where('shop_list.isopen',1);
$this->db->where('shop_list.id < ',$id);
$this->db->order_by('id','desc');
$this->db->limit($limit);
$query = $this->db->get();
if($query->num_rows() > 0){
return $query->result_array();
} else {
return [];
}
这里的$ID就是前端获取的,从下面JS。
JS文件:
$(function() {
// 获取容器元素
var $container = $("#containerpub");
var lastId = $("#containerpub .item:last").attr("id");
var site_url = 'https://www.zher.net/';
var base_url = 'https://www.zher.net/';
var isLoading = false; // 用于追踪是否正在加载数据
// 初始化Masonry布局
$container.imagesLoaded(function() {
$container.masonry({
itemSelector: ".item",
isAnimated: true
});
});
// 获取加载指示器元素,并初始化其状态
var $loadingIndicator = $("#loading").data("on", false);
// 滚动事件处理,加入去抖动机制
var scrollTimeout;
// 绑定窗口滚动事件
$(window).scroll(function() {
// 如果加载指示器已激活,则不执行后续操作
if ($loadingIndicator.data("on")) {
return;
}
clearTimeout(scrollTimeout);
scrollTimeout = setTimeout(function() {
// 检查是否滚动到页面底部(考虑页脚高度)
var scrollTop = $(document).scrollTop();
var documentHeight = $(document).height();
var windowHeight = $(window).height();
var footerHeight = $("#footer-main").height();
if (scrollTop > documentHeight - windowHeight - footerHeight) {
// 激活加载指示器并显示
isLoading = true;
$loadingIndicator.data("on", true).fadeIn();
// 发送AJAX请求获取更多内容
$.get(site_url + "/shop/photogetmore/" + lastId, function(jsonData) {
if (jsonData.length > 0) {
var $newItems = $([]);
$.each(jsonData, function(index, item) {
var html = '<div class="item" id="' + item.id + '">';
html += '<a href="' + site_url + '/shop/view/' + item.id + '">';
html += '<img class="aligncenter" src="' + base_url + 'plugins/st.php?src=' + base_url + 'uploads/shop/' + item.picurl + '&h=&w=213&zc=1" alt="' + item.title + '">';
html += '</a>';
// 简介
html += '<div class="intro">' + sb_substr(item.description,30) + '</div>';
// 浏览及评论数量(这里用库存量和折后价作为示例)
html += '<div class="opt-info">';
html += '<span>库存量 <em>' + (item.stock - item.sellnum) + '</em></span>';
html += '<span>折后价 <em>' + item.dprice + '</em></span>';
html += '</div>';
// 评论(这里只展示了一条评论的模板)
html += '<div class="cmt-boxst">';
html += '<div class="cmt-item">';
html += '<div class="avatar" data-user-id="' + item.uid + '">';
html += '<a href="' + site_url + 'shop/open/' + item.uid + '" class="toboxs">';
if (item.avatar) {
html += '<img alt="' + item.username + '" class="medium_avatar" src="' + base_url + item.avatar + '" onerror="noface();" />';
} else {
html += '<img alt="' + item.username + '" class="medium_avatar" src="/uploads/avatar/default.jpg" />';
}
html += '</a>';
html += '</div>';
html += '<div class="comment-hd">';
html += '<span class="username">' + item.username + '</span><br>';
html += '<time>' + item.time + ' 发布</time>'; // 假设friendlyDate是对应PHP中$this->myclass->friendly_date的函数
html += '</div>';
html += '</div>';
html += '</div>';
html += '</div>';
// 将新内容追加到容器中
//$('#containerpub').append(html);
$newItems = $newItems.add($(html));
});
// 确保新图片加载完成后再重新布局
$newItems.imagesLoaded(function() {
$container.append($newItems).masonry('appended', $newItems);
isLoading = false;
$loadingIndicator.fadeOut();
});
// 更新最后一个元素的ID,以便下次加载使用
lastId = jsonData[jsonData.length - 1].id;
} else {
isLoading = false;
$loadingIndicator.fadeOut();
Swal.fire({
title: '已加载完毕',
text: '没有更多数据可以加载了。',
icon: 'success',
timer: 2000 // 2秒后自动关闭弹窗
});
}
}).fail(function() {
// 请求失败时的回调函数,处理错误情况
isLoading = false;
$loadingIndicator.fadeOut();
Swal.fire({
title: '已加载完毕',
text: '没有更多数据可以加载了。',
icon: 'success',
timer: 2000 // 2秒后自动关闭弹窗
});
});
}
}, 200);
});
});
function sb_substr(str, length) {
// 如果字符串长度小于或等于指定的长度,则返回原字符串
if (str.length <= length) {
return str;
}
// 否则,返回截取后的字符串
return str.substring(0, length) + '...'; // 这里添加了'...'来表示字符串被截断了
}
这里就是JS根据前端的模板,赋值进去加载的,方法是:lastId = $("#containerpub .item:last").attr("id");
效果图:
共 0 次