Blog中新聞主頁開發(fā)設(shè)計文檔

新聞主頁

一绒北、功能需求分析

  1. 輪播圖
  2. 熱門文章列表
  3. 文章標(biāo)簽導(dǎo)航
  4. 文章列表
  5. 分類文章

二话侧、模型設(shè)計

這一部分是編寫程序筹陵,實現(xiàn)功能的==最重要的==一環(huán)。如果表設(shè)計不好沿彭,那么整個軟件的架構(gòu)就會顯得非承嗯椋混亂并且毫無章法,最重要的是到了后期非常難以維護喉刘,甚至?xí)?dǎo)致用戶數(shù)據(jù)丟失瞧柔。

2.1 表和字段分析

  1. 文章分類表
  2. 文章表
  3. 文章評論表
  4. 熱門文章表
  5. 輪播圖表

看起來很宏觀,好像對表之間的關(guān)系無從下手對吧饱搏?沒關(guān)系非剃!我們來上圖置逻!

006tNc79gy1g632t6kz6hj31400m9gpk.png

哇看起來還是好復(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代碼


(function () { // 新聞列表 letnewNavLi = $('.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)系方式

郵箱:psywency@foxmail.com

[Wency03lk@outlook.com]

碼云倉庫:https://gitee.com/Wencyyyyyy/SeniorDjprj

簡書:wencyyyyyy

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市愈犹,隨后出現(xiàn)的幾起案子键科,更是在濱河造成了極大的恐慌,老刑警劉巖甘萧,帶你破解...
    沈念sama閱讀 212,029評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件萝嘁,死亡現(xiàn)場離奇詭異梆掸,居然都是意外死亡扬卷,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評論 3 385
  • 文/潘曉璐 我一進店門酸钦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怪得,“玉大人,你說我怎么就攤上這事⊥搅担” “怎么了蚕断?”我有些...
    開封第一講書人閱讀 157,570評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長入挣。 經(jīng)常有香客問我亿乳,道長,這世上最難降的妖魔是什么径筏? 我笑而不...
    開封第一講書人閱讀 56,535評論 1 284
  • 正文 為了忘掉前任葛假,我火速辦了婚禮,結(jié)果婚禮上滋恬,老公的妹妹穿的比我還像新娘聊训。我一直安慰自己,他們只是感情好恢氯,可當(dāng)我...
    茶點故事閱讀 65,650評論 6 386
  • 文/花漫 我一把揭開白布带斑。 她就那樣靜靜地躺著,像睡著了一般勋拟。 火紅的嫁衣襯著肌膚如雪勋磕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,850評論 1 290
  • 那天敢靡,我揣著相機與錄音朋凉,去河邊找鬼。 笑死醋安,一個胖子當(dāng)著我的面吹牛杂彭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吓揪,決...
    沈念sama閱讀 39,006評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼亲怠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了柠辞?” 一聲冷哼從身側(cè)響起团秽,我...
    開封第一講書人閱讀 37,747評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎叭首,沒想到半個月后习勤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,207評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡焙格,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,536評論 2 327
  • 正文 我和宋清朗相戀三年图毕,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片眷唉。...
    茶點故事閱讀 38,683評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡予颤,死狀恐怖囤官,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蛤虐,我是刑警寧澤党饮,帶...
    沈念sama閱讀 34,342評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站驳庭,受9級特大地震影響刑顺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜饲常,卻給世界環(huán)境...
    茶點故事閱讀 39,964評論 3 315
  • 文/蒙蒙 一捏检、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧不皆,春花似錦贯城、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至犬耻,卻和暖如春踩晶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背枕磁。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評論 1 266
  • 我被黑心中介騙來泰國打工渡蜻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人计济。 一個月前我還...
    沈念sama閱讀 46,401評論 2 360
  • 正文 我出身青樓茸苇,卻偏偏與公主長得像,于是被迫代替她去往敵國和親沦寂。 傳聞我的和親對象是個殘疾皇子学密,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,566評論 2 349

推薦閱讀更多精彩內(nèi)容