新聞主頁
一绒北、功能需求分析
- 輪播圖
- 熱門文章列表
- 文章標(biāo)簽導(dǎo)航
- 文章列表
- 分類文章
二话侧、模型設(shè)計
這一部分是編寫程序筹陵,實現(xiàn)功能的==最重要的==一環(huán)。如果表設(shè)計不好沿彭,那么整個軟件的架構(gòu)就會顯得非承嗯椋混亂并且毫無章法,最重要的是到了后期非常難以維護喉刘,甚至?xí)?dǎo)致用戶數(shù)據(jù)丟失瞧柔。
2.1 表和字段分析
- 文章分類表
- 文章表
- 文章評論表
- 熱門文章表
- 輪播圖表
看起來很宏觀,好像對表之間的關(guān)系無從下手對吧饱搏?沒關(guān)系非剃!我們來上圖置逻!
哇看起來還是好復(fù)雜推沸!不過還算不錯,至少基本整理出了所有的字段和表券坞!后面我們再慢慢地拆分吧鬓催!【圖有點丑,對不起恨锚,手殘:cry:】
2.2模型定義
1 基本抽象模型
細心的朋友可能會發(fā)現(xiàn)宇驾,在這里并沒有在其他表中給出創(chuàng)建時間和更改時間猴伶,這怎么行呢课舍?!可是如果到每一個需要創(chuàng)建時間和更新時間的表中去創(chuàng)建字段又顯得太過冗余他挎,所以筝尾!我們需要自定義一個抽象模型類。這種抽象模型類在django執(zhí)行與數(shù)據(jù)庫的映射時并不會真正的創(chuàng)建對應(yīng)的表办桨,但是可以在模型設(shè)計的時候被繼承筹淫,以減少模型字段的冗余。DjangoORM真是非常貼心啦呢撞!
其次损姜,這里還設(shè)置了一個is_delete字段饰剥,用于表示模型是否可以刪除【并不是所有數(shù)據(jù)都是想刪就刪的】
話不多說,我們來創(chuàng)建
# 在utils目錄下摧阅,創(chuàng)建一個models.py文件汰蓉,在其中定義一個基類模型
from django.db import models
class BaseModel(models.Model):
"""
基類,公共字段用于去除冗余
"""
create_time = models.DateTimeField('創(chuàng)建時間', auto_now_add=True)
update_time = models.DateTimeField('更新時間', auto_now=True)
is_delete = models.BooleanField('邏輯刪除', default=False)#這個字段用于定義表是否會邏輯刪除
class Meta:
# 抽象類逸尖,用于繼承古沥,遷移時不會創(chuàng)建
abstract = True
2 其它模型建立
0.Notes!
在設(shè)置字段時娇跟,有三個值得注意的點:
==圖片==:一般我們不建議在數(shù)據(jù)庫中直接存儲圖片岩齿,首先因為需要將圖片轉(zhuǎn)換成二進制格式,其次是圖片的數(shù)據(jù)非常大【對于存入數(shù)據(jù)庫】苞俘,所以一般我們都采用url的方式存入圖片.
-
字段中定義一個名為 ==‘Meta‘==的源信息類盹沈,其中包含了
- db_name:即你要在數(shù)據(jù)庫中創(chuàng)建的表名,實際上Django為了節(jié)省開發(fā)者的時間吃谣,會根據(jù)app的名字自動在數(shù)據(jù)庫中創(chuàng)建用下劃線隔開的表名乞封,類似假如你的app名字是myapp,其中的模型類名叫mymodel岗憋,那么django對于==mymode==模型類相應(yīng)創(chuàng)建的名字就是tb_myapp_mymodel ,這樣雖然方便肃晚,但是名字有些過于長了,所以如果你想要==自己創(chuàng)建表名==仔戈,就在class Meta中采用db_table = “你想要的表名” 來設(shè)置关串,參見官方文檔[https://docs.djangoproject.com/en/2.2/ref/models/options/]
- ordering:設(shè)定字段查詢返回時的順序,如果是逆序监徘,則在字段名前加一個‘-’號即可晋修,也可以設(shè)立兩個字段,在前一字段相同時凰盔,按照第二個字段的順序來排序墓卦,與mysql有些類似,這個會涉及到時間成本上的耗費户敬,因為使用了這個操作的模型類落剪,在查詢時返回的的外鍵也會按照設(shè)定的order順序返回,具體的說明也請參看官方文檔[https://docs.djangoproject.com/en/2.2/ref/models/options/]
- verbose_name和verbose_name_plural 這兩個都是為模型設(shè)立一個簡單易讀的名字尿庐,前者是單數(shù)忠怖,后者是復(fù)數(shù),如果后者沒有設(shè)立那么屁倔,假如verbose_name = 'story'脑又,Django自動給它設(shè)置的復(fù)數(shù)名即為==‘storys’==而不是大家所知道的==‘stories’==
____==str==____方法: 我們在查詢對象時,一般希望輸出的是字符串,而不是一堆無意義的數(shù)字和亂嗎问麸,此時就需要用到這個方法
1. 分類表
from django.db import models
from utils.models import BaseModel
class Tag(BaseModel):
#文章分類表
name = models.CharField('標(biāo)簽名', max_length=64, help_text='標(biāo)簽名')
class Meta:#源信息
ordering = ['-update_time', '-id'] # 排序
db_table = "tb_tag" # 數(shù)據(jù)庫中建立表名
verbose_name = "文章標(biāo)簽" # 在admin站點中顯示的名稱
verbose_name_plural = verbose_name # 顯示的復(fù)數(shù)名稱往衷,因為是中文,所以復(fù)數(shù)名和非復(fù)數(shù)名無關(guān)
def __str__(self):
return self.name
2. 文章表模型
在創(chuàng)建之前严卖,我們需要回到之前的那個表關(guān)系圖席舍,理一理關(guān)于文章的表關(guān)系:
- 一個分類表中可以有多篇文章,一篇文章僅有一個分類【一對多】
- 一個作者可以發(fā)布多篇文章哮笆,一篇文章僅有一個作者【一對多】
class News(BaseModel):
"""
文章模型
"""
title = models.CharField('標(biāo)題', max_length=150, help_text='標(biāo)題')
digest = models.CharField('摘要', max_length=200, help_text='摘要')
content = models.TextField('內(nèi)容', help_text='內(nèi)容')
clicks = models.IntegerField('點擊量', default=0, help_text='點擊量')
image_url = models.URLField('圖片url', default='', help_text='圖片url')
tag = models.ForeignKey('Tag', on_delete=models.SET_NULL, null=True)
author = models.ForeignKey('user.User', on_delete=models.SET_NULL, null=True)
class Meta:
ordering = ['-update_time', '-id'] # 排序
db_table = "tb_news" # 指明數(shù)據(jù)庫表名
verbose_name = "新聞" # 在admin站點中顯示的名稱
verbose_name_plural = verbose_name # 顯示的復(fù)數(shù)名稱
def __str__(self):
return self.title
3.評論表
表關(guān)系:
- 一篇文章下可以有多條評論来颤,評論只能是一篇文章的【一對多】
- 一個用戶可以發(fā)出多條評論,一條評論只能來自于一個用戶【一對多】
- 一條評論下可以有多條子評論【多對多】//
class Comments(BaseModel):
"""
評論模型
"""
content = models.TextField('內(nèi)容', help_text='內(nèi)容')
author = models.ForeignKey('user.User', on_delete=models.SET_NULL, null=True)
news = models.ForeignKey('News', on_delete=models.CASCADE)
class Meta:
ordering = ['-update_time', '-id'] # 排序
db_table = "tb_comments" # 指明數(shù)據(jù)庫表名
verbose_name = "評論" # 在admin站點中顯示的名稱
verbose_name_plural = verbose_name # 顯示的復(fù)數(shù)名稱
def __str__(self):
return '<評論{}>'.format(self.id)
4.熱門文章模型
要求:
- 按照優(yōu)先度對文章熱度進行排序【點擊量稠肘、發(fā)布時間】
- 只取前三
class HotNews(BaseModel):
"""
熱門文章表
"""
priority = models.IntegerField('優(yōu)先級', help_text='優(yōu)先級')
news = models.OneToOneField('News', on_delete=models.CASCADE)
class Meta:
ordering = ['-update_time', '-id'] # 排序
db_table = "tb_hotnews" # 指明數(shù)據(jù)庫表名
verbose_name = "熱門新聞" # 在admin站點中顯示的名稱
verbose_name_plural = verbose_name # 顯示的復(fù)數(shù)名稱
def __str__(self):
return '<熱門新聞{}>'.format(self.id)
5. 輪播圖表
要求:
- 按照內(nèi)部優(yōu)先順序?qū)ξ恼屡判?/li>
- 可刪除
表關(guān)系:
- 與文章一一對應(yīng)
class Banner(BaseModel):
"""
輪播圖
"""
image_url = models.URLField('輪播圖url', help_text='輪播圖url')
priority = models.IntegerField('優(yōu)先級', help_text='優(yōu)先級')
news = models.OneToOneField('News', on_delete=models.CASCADE)
class Meta:
ordering = ['priority', '-update_time', '-id'] # 排序
db_table = "tb_banner" # 指明數(shù)據(jù)庫表名
verbose_name = "輪播圖" # 在admin站點中顯示的名稱
verbose_name_plural = verbose_name # 顯示的復(fù)數(shù)名稱
def __str__(self):
return '<輪播圖{}>'.format(self.id)
三福铅、文章標(biāo)簽導(dǎo)航
1、接口設(shè)計
類目 | 說明 |
---|---|
請求方式 | GET |
url | /news/index/ |
傳入?yún)?shù) | 無參數(shù) |
-
返回參數(shù)
返回新聞頁面项阴,只需要在模版渲染即可
2滑黔、后端
1. 說明:
- only方法:只拿取only中列出的字段。與之類似的是defer环揽,是除了defer中列出的字段略荡,其余都拿。
- 是否可以邏輯刪除:否歉胶,因為文章標(biāo)簽刪除之后汛兜,我們并不希望文章刪除
2. 代碼:
def index(request):
'''
index of news
新聞首頁視圖
url: '/news/index/'
:param request:
:return:
'''
#新聞標(biāo)簽
tags = Tag.objects.only('id','name').filter(is_delete = False)
context = {
'tags':tags,
}
return render(request,'news/index.html',context=context)
3、前端
# 修改templates/news/index.html中 news-nav部分代碼如:
<!-- news-nav start-->
<nav class="news-nav">
<ul class="clearfix">
<li class="active"><a href="javascript:void(0)">最新資訊</a></li>
//迭代出所有標(biāo)簽
{% for tag in tags %}
<li><a href="javascript:void(0)" data-id="{{ tag.id }}">{{ tag.name }}</a>
</li>
{% endfor %}
</ul>
</nav>
<!-- news-nav end -->
四通今、新聞列表功能
1粥谬、業(yè)務(wù)流程分析
- 判斷前端傳遞的標(biāo)簽
2、接口設(shè)計
類目 | 說明 |
---|---|
請求方式 | GET |
url | /news/list/ |
參數(shù)格式 | 查詢參數(shù) |
-
參數(shù)說明
參數(shù)說明 類型 是否必須 描述 tag integrity 是 標(biāo)簽分類id page integrity 是 當(dāng)前文章頁數(shù) -
返回結(jié)果
{ "errno": "0", "errmsg": "", "data": { "total_pages": 61, "news": [ { "digest": "在python用import或者from...import或者from...import...as...來導(dǎo)入相應(yīng)的模塊衡创,作用和使用方法與C語言的include頭文件類似帝嗡。其實就是引入...", "title": "import方法引入模塊詳解", "author": "python", "image_url": "/media/jichujiaochen.jpeg", "tag_name": "Python基礎(chǔ)", "update_time": "2018年12月17日 14:48" }, { "digest": "如果你原來是一個php程序員晶通,你對于php函數(shù)非常了解(PS:站長原來就是一個php程序員)璃氢,但是現(xiàn)在由于工作或者其他原因要學(xué)習(xí)python,但是p...", "title": "給曾經(jīng)是phper的程序員推薦個學(xué)習(xí)網(wǎng)站", "author": "python", "image_url": "/media/jichujiaochen.jpeg", "tag_name": "Python基礎(chǔ)", "update_time": "2018年12月17日 14:48" } ] } }
3狮辽、后端
這里采用了一個在查詢較大量的數(shù)據(jù)時一也,比較高效率的操作:==select_related==,此操作查詢數(shù)據(jù)會把相關(guān)的所有外鍵字段全部放到臨時內(nèi)存中存好,也就是犧牲了一部分的空間喉脖,但優(yōu)點是節(jié)省了一次次去數(shù)據(jù)庫中拿數(shù)據(jù)的時間椰苟,當(dāng)拿的數(shù)據(jù)較多時,建議采用這種“空間換時間”的操作树叽。當(dāng)然舆蝴!也需要你有空間啦:dog:
class NewListview(View):
'''
新聞列表視圖
url:'/news/list/'
參數(shù):tag,page
'''
def get(self, request):
#1、得到文章類別的id
try:
# 這里強轉(zhuǎn)int有可能會報錯,所以try一下
tag_id = int(request.GET.get('tag', 0))
except Exception as e:
logger.error('標(biāo)簽錯誤:\n{}'.format(e))
tag_id = 0
#2洁仗、得到頁數(shù)层皱,與tag同理
try:
page = int(request.GET.get('page', 0))
except Exception as e:
logger.error('頁碼錯誤:\n{}'.format(e))
page = 1
#3、得到新聞的相關(guān)字段
#這里采用annonate【意為注釋赠潦,類似于數(shù)據(jù)庫中的as】
news_queryset = News.objects.values('id', 'title', 'digest', 'image_url', 'update_time'). annotate(
tag_name=F('tag__name'), author=F('author__username'))
#后一個條件是叫胖,假如沒有tag_id
news = news_queryset.filter(is_delete=False, tag_id=tag_id) or news_queryset.filter(is_delete=False)
#4、希望對新聞進行分頁操作她奥,導(dǎo)入一個paginator
paginator = Paginator(news, constants.PERPAGE_NEWS_COUNT)
#5 獲取頁面數(shù)據(jù)瓮增,get_page可以容錯
news_info = paginator.get_page(page)#如果傳入的page不存在,也可以返回一個合法的頁面
data = {
'total_pages': paginator.num_pages,
'news': list(news_info)
}
return Json_response(data=data)
因為在這里哩俭,Json_response【這是自定義的绷跑,與原生的JsonResponse不同,并非編者寫錯】并不能返回我們熟知的時間凡资,所以我們要自定義一個序列化器
# json編碼器
#放在一個固定的py文件中你踩,那個文件用于定義返回數(shù)據(jù)格式,然后再采用import方式導(dǎo)入
# 自定義序列化器讳苦,處理時間字段
class MyJSONEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, datetime.datetime):
return o.astimezone().strftime('%Y-%m-%d %H:%M:%S') # 轉(zhuǎn)換為本地時間
def json_response(errno=Code.OK, errmsg='', data=None, kwargs=None):
json_dict = {
'errno': errno,
'errmsg': errmsg,
'data': data
}
if kwargs and isinstance(kwargs, dict) :
json_dict.update(kwargs)
return JsonResponse(json_dict, encoder=MyJSONEncoder)
4带膜、前端
<!-- news-contain start 清空 ul中的內(nèi)容 -->
<div class="news-contain">
<ul class="news-list">
</ul>
</div>
<!-- news-contain end -->
采用js
// static/js/news/index.js
$(function () {
// 新聞列表
let $newNavLi = $('.news-nav ul li'); // 標(biāo)簽li
let iPage = 1; // 默認第一頁
let iTotalPage = 1; // 默認總頁數(shù)為1
let iCurrentTagId = 0; // 默認分類標(biāo)簽為0
let bIsLoadData = true; // 是否正在向后臺加載數(shù)據(jù)
fn_load_content();
// 點擊分類標(biāo)簽
$newNavLi.click(function () {
// 點擊分類標(biāo)簽,則為點擊的標(biāo)簽加上一個active的class屬性
// 并移除其他兄弟元素上的active的class屬性
$(this).addClass('active').siblings('li').removeClass('active');
// 獲取綁定在data-id屬性上的tag_id
let iClickTagId = $(this).children('a').attr('data-id');
if (iClickTagId !== iCurrentTagId){
iCurrentTagId = iClickTagId; // 記錄當(dāng)前分類id
// 重置分頁參數(shù)
iPage = 1;
iTotalPage = 1;
fn_load_content()
}
});
// 頁面滾動加載
$(window).scroll(function () {
// 瀏覽器窗口高度
let showHeigtht = $(window).height();
// 整個網(wǎng)頁高度
let pageHeight = $(document).height();
//頁面可以滾動的距離
let canScrollHeight = pageHeight - showHeigtht;
// 頁面滾動了多少鸳谜, 整個是隨著頁面滾動實時變化的
let nowScroll = $(document).scrollTop();
if ((canScrollHeight - nowScroll) < 100){
if(!bIsLoadData){
bIsLoadData = true;
//判斷頁數(shù)膝藕,去更新新聞,小于總數(shù)才加載
if(iPage < iTotalPage){
iPage += 1;
fn_load_content();
}else {
message.showInfo('已全部加載咐扭,沒有更多內(nèi)容芭挽!');
$('a.btn-more').html('已全部加載,沒有更多內(nèi)容蝗肪!')
}
}
}
});
// 向后端獲取新聞列表數(shù)據(jù),ur;與之對應(yīng)
function fn_load_content() {
$.ajax({
url: '/news/list/',
type: 'GET',
data:{
tag: iCurrentTagId,
page: iPage
},
dataType: 'json',
success: function (res) {
if(res.errno === '0'){
iTotalPage = res.data.total_pages;
if(iPage === 1){
// 第一頁清空內(nèi)容
$('.news-list').html('')
}
res.data.news.forEach(function (one_news) {
let content = ` <li class="news-item">
<a class="news-thumbnail"
target="_blank">
<img src="${one_news.image_url}" alt="${one_news.title}"
title="${one_news.title}">
</a>
<div class="news-content">
<h4 class="news-title"><a
href="#">${one_news.title}</a>
</h4>
<p class="news-details">${one_news.digest}</p>
<div class="news-other">
<span class="news-type">${one_news.tag_name}</span>
<span class="news-time">${one_news.update_time}</span>
<span class="news-author">${one_news.author}</span>
</div>
</div>
</li>`;
$('.news-list').append(content);
});
// $('.news-list').append($('<a href="javascript:void(0);" class="btn-more">滾動加載更多</a>'));
//數(shù)據(jù)加載完畢袜爪,設(shè)置正在加載數(shù)據(jù)變量為false,表示當(dāng)前沒有加載數(shù)據(jù)
bIsLoadData = false;
$('a.btn-more').html('滾動加載更多')
}else {
// 加載失敗薛闪,打印錯誤信息
message.showError(res.errmsg)
}
},
error: function () {
message.showError('服務(wù)器超時辛馆,請重試!')
}
});
}
});
五豁延、熱門新聞功能
1昙篙、接口設(shè)計
類目 | 說明 |
---|---|
請求方式 | GET |
url | /news/index/ |
參數(shù)格式 | 無參數(shù) |
功能比較簡單,直接返回新聞頁面诱咏,采用模版渲染的方式
2苔可、后端
同樣地,采用select_related袋狞,為防止硬編碼焚辅,我們設(shè)置一個顯示熱門新聞條數(shù)的變量存入constants.py中映屋,命名為HOTNEWS_SHOW_COUNT = 3
def index(request):
'''
index of news
新聞首頁視圖
url:/news/index/
:param request:
:return:
'''
#新聞標(biāo)簽
tags = Tag.objects.only('id','name').filter(is_delete = False)
#熱門新聞
hotnews = HotNews.objects.select_related('news').only('news__title','news__image_url','news_id')\
.filter(is_delete = False).order_by('priority','-news__clicks')[:constants.HOTNEWS_SHOW_COUNT]
context = {
'tags':tags,
'hotnews':hotnews
}
return render(request,'news/index.html',context=context)
3、前端
<!-- 修改templates/news/index.html -->
<ul class="recommend-news">
//迭代出hotnews
{% for item in hot_news %}
<li>
<a target="_blank">
<div class="recommend-thumbnail">
<img src="{{ item.news.image_url }}" alt="title">
</div>
<p class="info">{{ item.news.title }}</p>
</a>
</li>
{% endfor %}
</ul>
<!-- recommend-news end -->
六同蜻、輪播圖功能
1秧荆、接口設(shè)計
類目 | 說明 |
---|---|
請求方式 | GET |
url | /news/bannner/ |
參數(shù)格式 | 無參數(shù) |
返回結(jié)果
{
"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、后端
1 說明:
- annotate: 這里使用到annotate函數(shù)埃仪,此函數(shù)會在返回的對象中給相應(yīng)的字段加上別名乙濒,此時在返回的數(shù)據(jù)集中,可以采用在annotate中聲明的別名來查詢數(shù)據(jù)卵蛉,想看更多的細節(jié)颁股,請參考官方文檔[https://docs.djangoproject.com/en/2.2/topics/db/queries/]
- constants.BANNER_SHOW_COUNT: 如前所說,是一個常量
2 代碼
class NewsBannerView(View):
'''
輪播圖視圖
顯示constants傻丝。BANNNER_SHOW_COUNT = 6條輪播圖
與文章形成一對一關(guān)系
url:/news/banner/
'''
def get(self,request):
banners = Banner.objects.values('image_url', 'news_id').annotate(
news_title=F('news__title')
).filter(is_delete=False)[:constants.BANNER_SHOW_COUNT]
data = {
'banners': list(banners)
}
return Json_response(data=data)
3甘有、前端
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">
<!-- 按鈕數(shù)量必須和圖片一致 -->
</ul>
</div>
<!-- banner end -->
js代碼
newNavLi = $('.news-nav ul li'); // 標(biāo)簽li
let iPage = 1; // 默認第一頁
let iTotalPage = 1; // 默認總頁數(shù)為1
let iCurrentTagId = 0; // 默認分類標(biāo)簽為0
let bIsLoadData = true; // 是否正在向后臺加載數(shù)據(jù)
fn_load_content();
// 點擊分類標(biāo)簽
$newNavLi.click(function () {
// 點擊分類標(biāo)簽,則為點擊的標(biāo)簽加上一個active的class屬性
// 并移除其他兄弟元素上的active的class屬性
$(this).addClass('active').siblings('li').removeClass('active');
// 獲取綁定在data-id屬性上的tag_id
let iClickTagId = $(this).children('a').attr('data-id');
if (iClickTagId !== iCurrentTagId){
iCurrentTagId = iClickTagId; // 記錄當(dāng)前分類id
// 重置分頁參數(shù)
iPage = 1;
iTotalPage = 1;
fn_load_content()
}
});
// 頁面滾動加載
$(window).scroll(function () {
// 瀏覽器窗口高度
let showHeigtht = $(window).height();
// 整個網(wǎng)頁高度
let pageHeight = $(document).height();
//頁面可以滾動的距離
let canScrollHeight = pageHeight - showHeigtht;
// 頁面滾動了多少葡缰, 整個是隨著頁面滾動實時變化的
let nowScroll = $(document).scrollTop();
if ((canScrollHeight - nowScroll) < 100){
if(!bIsLoadData){
bIsLoadData = true;
//判斷頁數(shù)亏掀,去更新新聞,小于總數(shù)才加載
if(iPage < iTotalPage){
iPage += 1;
fn_load_content();
}else {
message.showInfo('已全部加載泛释,沒有更多內(nèi)容滤愕!');
$('a.btn-more').html('已全部加載,沒有更多內(nèi)容怜校!')
}
}
}
});
// 向后端獲取新聞列表數(shù)據(jù)
function fn_load_content() {
$.ajax({
url: '/news/',
type: 'GET',
data:{
tag: iCurrentTagId,
page: iPage
},
dataType: 'json',
success: function (res) {
if(res.errno === '0'){
iTotalPage = res.data.total_pages;
if(iPage === 1){
// 第一頁清空內(nèi)容
$('.news-list').html('')
}
res.data.news.forEach(function (one_news) {
let content = ` <li class="news-item">
<a class="news-thumbnail"
target="_blank">
<img src="${one_news.image_url}" alt="${one_news.title}"
title="${one_news.title}">
</a>
<div class="news-content">
<h4 class="news-title"><a
href="#">${one_news.title}</a>
</h4>
<p class="news-details">${one_news.digest}</p>
<div class="news-other">
<span class="news-type">${one_news.tag_name}</span>
<span class="news-time">${one_news.update_time}</span>
<span class="news-author">${one_news.author}</span>
</div>
</div>
</li>`;
$('.news-list').append(content);
});
// $('.news-list').append($('<a href="javascript:void(0);" class="btn-more">滾動加載更多</a>'));
//數(shù)據(jù)加載完畢间影,設(shè)置正在加載數(shù)據(jù)變量為false,表示當(dāng)前沒有加載數(shù)據(jù)
bIsLoadData = false;
$('a.btn-more').html('滾動加載更多')
}else {
// 加載失敗茄茁,打印錯誤信息
message.showError(res.errmsg)
}
},
error: function () {
message.showError('服務(wù)器超時魂贬,請重試!')
}
})
}
// 新聞輪播圖功能
fn_load_banner(); // 先加載banner
let $banner = $('.banner'); // banner容器div
let $picLi = $('.banner .pic li'); // 圖片li標(biāo)簽
let $pre = $('.banner .prev'); // 上一張
let $next = $('.banner .next'); // 下一張
let $tabLi = $('.banner .tab li'); // 按鈕
let index = 0; // 當(dāng)前索引
// 導(dǎo)航小圓點
$tabLi.click(function () {
index = $(this).index();
$(this).addClass('active').siblings('li').removeClass('active');//點擊小圓點裙顽,小圓點顏色變化
$picLi.eq(index).fadeIn(1500).siblings('li').fadeOut(1500);
});
// 點擊切換上一張
$pre.click(()=> {
index --;
if(index<0){
index = $tabLi.length - 1 // 最后一張
}
$tabLi.eq(index).addClass('active').siblings('li').removeClass('active');
$picLi.eq(index).fadeIn(1500).siblings('li').fadeOut(1500);
});
// 點擊切換下一張
$next.click(()=>{
auto();
});
// 圖片向前滑動
function auto() {
index ++;
index %= $tabLi.length;
$tabLi.eq(index).addClass('active').siblings('li').removeClass('active');
$picLi.eq(index).fadeIn(1500).siblings('li').fadeOut(1500)
}
// 定時器
let timer = setInterval(auto, 2500);
$banner.hover(
()=>{
clearInterval(timer)
},
()=>{
timer = setInterval(auto, 2500);
}
);
// 定義向后端獲取banner
});
七付燥、聯(lián)系方式
碼云倉庫:https://gitee.com/Wencyyyyyy/SeniorDjprj
簡書:wencyyyyyy