VI. 轮播图功能
1>接口设计
- 接口说明:
类目 | 说明 |
---|---|
请求方法 | GET |
url定义 | /news/banners/ |
参数格式 | 无参数 |
返回结果:
{
"errno": "0",
"errmsg": "OK",
"data": {
"banners": [
{
'image_url': '/media/jichujiaochen.jpeg',
'news_id': 221,
'news_title': "python 算法快速排序"
},
{
"image_url": "/media/python_advanced.jpg",
"news_id": 707,
"news_title": "Python 序列与映射的解包操作"
}
]
}
}
2>后端代码
2.1>视图代码
# 在news目录下views.py中创建如下视图
class NewsBannerView(View):
"""
轮播图
GET /news/banners/
"""
def get(self, request):
# 读取到图片,文章id和标题, 由于标题是外键, 发送json的话就需要重命名
banners = Banner.objects.values('image_url', 'news_id').annotate(
news_title=F('news__title')).filter(is_delete=False)[:constants.SHOW_BANNER_COUNT]
data = {
'banners': list(banners)
}
return json_response(data=data)
2.2>定义常量
# 在news目录下constants.py中定义如下常量
# banner页展示数量
SHOW_BANNER_COUNT = 6
2.3>路由
# news目录下urls.py中定义如下路由:
from django.urls import path
from . import views
# url的命名空间
app_name = 'news'
urlpatterns = [
path('', views.index, name='index'), # 将这条路由命名为index
path('news/', views.NewsListView.as_view(), name='news_list'),
path('news/banners/', views.NewsBannerView.as_view(), name='news_banner')
]
3>前端代码
3.1>html代码
<!-- 修改templates/news/index.html中banner部分的代码如下 -->
<!-- banner start -->
<div class="banner">
<ul class="pic">
<!--淡入淡出banner-->
</ul>
<a href="javascript:void(0);" class="btn prev">
<i class="PyWhich py-arrow-left"></i></a>
<a href="javascript:void(0);" class="btn next">
<i class="PyWhich py-arrow-right"></i></a>
<ul class="tab">
<!-- 按钮数量必须和图片一致 -->
</ul>
</div>
<!-- banner end -->
3.2>js代码
<!-- static/js/news/index.js -->
/*=== bannerStart ===*/
$(function () {
// 轮播图
// 1.加载轮播图数据
function fn_load_banner() {
// 发送ajax 获取数据
$
.ajax({
url: '/news/banners/',
type: 'GET',
dataType: 'json',
async: false // 设置为同步
})
.done((res) => {
if (res.errno === '0') {
let content = '';
let tab_content = '';
res.data.banners.forEach((one_banner, index) => {
if (index === 0) { // 第一页 加active属性
content = `<li style="display:block;"><a href="/news/${one_banner.news_id}/">
<img src="${one_banner.image_url}" alt="${one_banner.news_title}"></a></li>`;
tab_content = '<li class="active"></li>';
} else {
content = `<li><a href="/news/${one_banner.news_id}/"><img src="${one_banner.image_url}" alt="${one_banner.news_title}"></a></li>`;
tab_content = '<li></li>';
}
$('.pic').append(content);
$('.tab').append(tab_content)
})
} else {
message.showError(res.errmsg)
}
})
.fail(() => {
message.showError('服务器超时,请重试!')
})
}
fn_load_banner();
// 定义变量
let $banner = $('.banner'); // banner容器div
let $picLi = $('.banner .pic li'); // 图片li标签
let $pre = $('.banner .prev'); // 上一张
let $next = $('.banner .next'); // 下一张
let $tabLi = $('.banner .tab li'); // 按钮
let index = 0; // 当前索引
// 2.点击导航按钮切换
$tabLi.click(function () {
index = $(this).index();
// 点击当前li加上active, 并将所有兄弟li的active去掉
$(this).addClass('active').siblings('li').removeClass('active');
// 当前图片淡入, 其它兄弟li的图片淡出
$picLi.eq(index).fadeIn(1500).siblings('li').fadeOut(1500);
});
// 3.上一张,下一张
// 点击切换上一张
$pre.click(()=> {
index --;
if(index<0){
// 如果当前索引是0,那么点击后index小于0,我们让他退回到最后一张
index = $tabLi.length - 1 // 最后一张
}
// 当前索引的li加active, 其他li去掉active
$tabLi.eq(index).addClass('active').siblings('li').removeClass('active');
// 当前图片淡入, 其它li的图片淡出
$picLi.eq(index).fadeIn(1500).siblings('li').fadeOut(1500);
});
// 点击切换下一张
$next.click(()=>{
// 这里单独定义方法, 是为了可以同时使用 定时 和 手动切换
auto();
});
// 图片向前滑动
function auto() {
index ++;
// 模等于, 当index为6时, 其模为0, 就重新从0开始, 也就起到一个循环的作用
index %= $tabLi.length;
$tabLi.eq(index).addClass('active').siblings('li').removeClass('active');
$picLi.eq(index).fadeIn(1500).siblings('li').fadeOut(1500)
}
// 4.自动切换
let timer = setInterval(auto, 2500);
// 5.鼠标滑入 暂停自动播放
$banner.hover(
()=>{
// 鼠标移入时, 清除定时器
clearInterval(timer)
},
()=>{
// 鼠标移出时, 重新添加定时器
timer = setInterval(auto, 2500);
}
);
/*=== bannerEnd ===*/
3.3>调整index.css
首页功能做好了,但是有一些图片没有填充满我们的div, 所以来修改一下
.recommend-news li .recommend-thumbnail img {
width: 100%;
height: 100%; /*<<<*/
transition: all 300ms ease-out;
}
.banner .tab {
width: 140px; /*<<<*/
height: 12px;
position: absolute;
left: 50%;
bottom: 22px;
margin-left: -49px;
display: flex;
}
.pic li a img {
width: 800px; /*<<<*/
height: 100%;
}
到此, 首页页面的所有功能均已完成