仿美團詳情頁與購物車源碼-首頁實現

来源:https://www.cnblogs.com/chenyingying0/archive/2020/01/09/12170409.html
-Advertisement-
Play Games

效果圖 首先是index.html <!DOCTYPE html> <html> <head> <title>首頁</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-sc ...


效果圖

首先是index.html

<!DOCTYPE html>
<html>
<head>
    <title>首頁</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
    <script type="text/javascript">
    (function() {
        var docEl = document.documentElement;
        function setRemUnit() {
            // 獲取到rem的基準值
            var rem = docEl.clientWidth / 10;
            // 動態設置html根元素的font-size
            docEl.style.fontSize = rem + 'px';
        }
        setRemUnit();
        // 視窗大小變化時 觸發
        window.addEventListener('resize', setRemUnit);
        // 視窗出現在當前屏幕時 (有瀏覽器相容性)
        window.addEventListener('pageshow', function(e) {
            if (e.persisted) {
                setRemUnit();
            }
        });
    })();
    </script>
    <link rel="stylesheet" type="text/css" href="../lib/reset.css"><!-- 樣式重置 -->
    <link rel="stylesheet" type="text/css" href="./searchBar/searchBar.css"><!-- 搜索框 -->
    <link rel="stylesheet" type="text/css" href="./category/category.css"><!-- 美食分類 -->
    <link rel="stylesheet" type="text/css" href="./contentList/contentList.css"><!-- 美食列表 -->
    <link rel="stylesheet" type="text/css" href="./starScore/starScore.css"><!-- 星級評分 -->
    <link rel="stylesheet" type="text/css" href="../common/bottomBar/bottomBar.css"><!-- 底部菜單欄 -->
    <link rel="stylesheet" type="text/css" href="./header/header.css"><!-- 頭部 -->
</head>

<body>
    <!--頭部開始-->
    <div class="header">
        <div class="search-bar">
            <div class="bar-location">
                <div class="location-icon"></div>
                <div class="location-text">鄭州市</div>
            </div>
            <div class="search-btn">
                <p class="place-holder">雞翅</p>
            </div>
        </div>
        <img class="header-img" src="https://app.nihaoshijie.com.cn/upload/bannertemp.e8a6fa63.jpg">
    </div>
        <!--頭部結束-->
        <!--類目結束-->
        <div class="category-content clearfix"></div>
        <!--類目結束-->
        <!--商家列表開始-->
        <div class="list-content">
            <h4 class="list-title">
            <span class="title-line"></span>
            <span>附近商家</span>
            <span class="title-line"></span>
        </h4>
            <div class="list-wrap"></div>
            <div class="loading">載入中</div>
        </div>
        <!--商家列表結束-->
        <!--底部欄開始-->
        <div class="bottom-bar"></div>
        <!--底部欄結束-->
        <script type="text/javascript" src="../lib/jquery.min.js"></script>
        <script type="text/javascript" src="./starScore/starScore.js"></script><!-- 星級評分 -->
        <script type="text/javascript" src="./category/category.js"></script><!-- 美食分類 -->
        <script type="text/javascript" src="../common/bottomBar/bottomBar.js"></script><!-- 底部菜單欄 -->
        <script type="text/javascript" src="./contentList/contentList.js"></script><!-- 美食列表 -->
</body>
</html>

接下來是用到的css文件

樣式重置reset.css

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
    display: block;
}
body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
    content: '';
    content: none;
}
table {
    border-collapse: collapse;
    border-spacing: 0;
}

.clearfix::after {
    content: ' ';
    visibility: hidden;
    display: block;
    height: 0;

    clear: both;
}

.one-line {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.hide {
    display: none;
}

搜索框 searchBar.css

.search-bar {
    width: 100%;
    height: 1.066667rem;
    position: absolute;

    display: flex;

    flex-direction: row;

    align-items: center;

    justify-content: center;

    padding-top: 0.213333rem;

}

.search-bar .bar-location {
    margin-right: 0.533333rem;
    border-radius: 0.346667rem;
    background-color: rgba(0,0,0,0.33);

    width: 2.453333rem;
    height: 0.746667rem;
}
.search-bar .location-icon {
    display: inline-block;
    width: 0.4rem;
    height: 0.533333rem;
    vertical-align: 0.213333rem;
    margin-left: 0.16rem;
    background-image: url('../img/locationIcon.png');
    background-size: cover;
}

.search-bar .location-text {
    position: relative;
    display: inline-block;
    font-size: 0.373333rem;
    color: #fff;
    vertical-align: 0.32rem;
    margin-left: -0.08rem;
}
.search-bar .location-text::after {
    content: ' ';
    display: block;
    width: 0.373333rem;
    height: 0.373333rem;
    background-image: url('../img/arrowIcon.png');
    background-size: cover;
    position: absolute;
    right: -0.4rem;
    top: -0.026667rem;
}
.search-bar .search-btn {
    position: relative;
    width: 4.533333rem;
    height: 0.8rem;
    background-color: #fff;
    border-radius: 0.533333rem;
}
.search-bar .search-btn::before {
    content: ' ';
    display: block;
    width: 0.373333rem;
    height: 0.373333rem;
    background-image: url('../img/searchIcon.png');
    background-size: cover;
    top: 0.213333rem;
    left: 0.266667rem;
    position: absolute;
}
.search-bar .place-holder {
    color: #a9a9a9;
    font-size: 0.373333rem;
    height: 100%;
    line-height: 0.8rem;
    margin-left: 0.746667rem;
}

美食分類 category.css

.category-content {
    padding-bottom: 0.266667rem;

}
.category-content .category-item {
    float: left;
    width: 25%;
    padding-top: 0.373333rem;
    font-size: 0.346667rem;

    display: flex;

    flex-direction: column;
    align-items: center;
    
}
.category-content .item-icon {
    width: 1.253333rem;
}
.category-content .item-name {
    margin-top: 0.373333rem;
}

美食列表 contentList.css

.list-content {
    overflow: hidden;
    padding-bottom: 1.333333rem;
}

.list-content .list-title {
    text-align: center;
    font-size: 0.426667rem;
    margin-top: 0.373333rem;
    margin-bottom: 0.133333rem;
}
.list-content .title-line {
    display: inline-block;
    border-bottom: 0.026667rem solid #949494;
    height: 0.026667rem;
    width: 0.8rem;
    margin-left: 0.106667rem;
    margin-right: 0.106667rem;
    margin-bottom: 0.106667rem;
}
.loading {
    padding-bottom: 0.266667rem;
    padding-top: 0.266667rem;
    font-size: 0.426667rem;
    text-align: center;
    color: #ccc;
}
.r-item-content {
    display: flex;
    padding-top: 0.4rem;
    padding-bottom: 0.4rem;
    margin-left: 0.266667rem;
    margin-right: 0.266667rem;
    color: #656565;
    position: relative;
}

.r-item-content .item-img {
    width: 2.293333rem;
    height: 1.733333rem;
    border: 0.026667rem solid #e4e4e4;
    
}

.r-item-content .item-info-content {
    flex: 1;
    margin-left: 0.186667rem;
    overflow: hidden;
}
.r-item-content .brand {
    position: absolute;
    left: 0.026667rem;
    top: 0.426667rem;
    font-size: 0.32rem;
    padding: 0.053333rem;
    color: #fff;
}
.r-item-content .brand-pin {
    background-color: #ffa627;
}
.r-item-content .brand-xin {
    background-color: #21c56c;
}

.r-item-content .item-title {
    margin-top: 0.08rem;
    font-size: 0.426667rem;
    font-weight: 500;
    color: #333;
}
.r-item-content .item-desc {
    margin-top: 0.346667rem;
    font-size: 0.32rem;
}

.r-item-content .item-count {
    float: left;
    margin-left: 0.133333rem;
}
.r-item-content .item-time {
    float: right;
}
.r-item-content .item-distance {
    float: right;
}
.r-item-content .item-score {
    float: left;
}
.r-item-content .item-price {
    margin-top: 0.266667rem;
    font-size: 0.32rem;
    height: 0.64rem;
}
.r-item-content .other-info {
    color: #898989;
    margin-top: 0.186667rem;
    font-size: 0.32rem;
    display: flex;
}

.r-item-content .other-tag {
    width: 0.373333rem;
    height: 0.373333rem;
}

.other-content {
    margin-left: 0.08rem;
    height: 0.373333rem;
    width: 6.133333rem;
    margin-top: 0.026667rem;
}

星級評分 starScore.css

.star-score .star {
    width: 0.266667rem;
    height: 0.266667rem;
    float: left;
    background-size: cover;
}
.star-score .fullstar {
    background-image: url('./img/fullstar.png');
}
.star-score .halfstar {
    background-image: url('./img/halfstar.png');
}
.star-score .nullstar {
    background-image: url('./img/gray-star.png');
}

底部菜單欄 bottomBar.css

.bottom-bar {
    position: fixed;
    bottom: 0;
    width: 100%;
    height: 1.333333rem;
    display: flex;
    border-top: 1px solid #b6b6b6;

    background-color: rgba(246,246,246,0.95);
}

.bottom-bar .btn-item {
    flex: 1;
    display: flex;
    font-size: 0.293333rem;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: #999;
}
.bottom-bar .tab-icon {
    margin-bottom: 0.106667rem;
    width: 0.666667rem;
    height: 0.666667rem;
    background-size: cover;
}

.bottom-bar .index.btn-item .tab-icon {
    background-image: url('./img/homeIcon.png');
}
.bottom-bar .my.btn-item .tab-icon {
    background-image: url('./img/myIcon.png');
}
.bottom-bar .order.btn-item .tab-icon {
    background-image: url('./img/orderIcon.png');
}
.bottom-bar .btn-item.active {
    color: #000;
}
.bottom-bar .index.btn-item.active .tab-icon {
    background-image: url('./img/homeIconActive.png');
}
.bottom-bar .my.btn-item.active .tab-icon {
    background-image: url('./img/myIconActive.png');
}
.bottom-bar .order.btn-item.active .tab-icon {
    background-image: url('./img/orderIconActive.png');
}

頭部 header.css

.header {
    position: relative;
}

.header .header-img {
    width: 100%;
    height: 4.746667rem;
}

接下來是js文件,乖乖引入jquery不用說

星級評分 starScore.js

(function(){

    // 得分模版字元串
    var itemTmpl = '<div class="star-score">$starstr</div>';


    function _getStars(){

        var _score = this.score.toString();

        //4.4
        var scoreArray = _score.split('.');


        // 滿星
        var fullstar = parseInt(scoreArray[0]);

        // 半星
        var halfstar = parseInt(scoreArray[1]) >=5 ? 1: 0;

        // 0星
        var nullstar = 5 - fullstar - halfstar;

        var starstr = '';

        for (var i = 0 ; i < fullstar ; i++) {
            starstr += '<div class="star fullstar"></div>'
        }

        for (var j = 0 ; j < halfstar ; j++) {
            starstr += '<div class="star halfstar"></div>'
        }


        for (var k = 0 ; k < nullstar ; k++) {
            starstr += '<div class="star nullstar"></div>'
        }


        return itemTmpl.replace('$starstr',starstr);

    }

    window.StarScore = function(score){
        this.score = score || '';

        this.getStars = _getStars;
    }

})();

美食分類 category.js

(function(){

    // 類目的模版字元串
    var itemTmpl = '<div class="category-item">'+
                        '<img class="item-icon" src=$url />'+
                        '<p class="item-name">$name</p>'+
                    '</div>';



    /** 
    *  渲染category元素
    * param 
    */
    function initCategory(){
        // 獲取category的數據

        $.get('../json/head.json', function(data){
            console.log(data);

            var list = data.data.primary_filter.splice(0,8);

            list.forEach(function(item, index){
                var str = itemTmpl
                .replace('$url',item.url)
                .replace('$name',item.name);


                $('.category-content').append($(str));
            });
        });
    }


    /** 
    *  綁定item的click事件
    * param 
    */
    function addClick(){
        $('.category-content').on('click','.category-item', function(){
            alert(1);
        });
    }


    function init() {
        initCategory();
        addClick();
    }

    init();
})();

底部菜單欄 bottomBar.js

(function(){
    var itemTmpl = '<a class="$key btn-item" href="../$key/$key.html">'+
                      '<div class="tab-icon"></div>'+
                      '<div class="btn-name">$text</div>'+
                   '</a>'


    function init(){
        var items = [{
            key: 'index',
            text: '首頁'
        },{
            key: 'order',
            text: '訂單'
        },{
            key: 'my',
            text: '我的'
        }];


        var str = '';

        items.forEach(function(item){
            str += itemTmpl.replace(/\$key/g,item.key)
                            .replace('$text',item.text)
        });


        $('.bottom-bar').append($(str));


        // 找到當前頁面的url來確定key值
        var arr = window.location.pathname.split('/');
        var page = arr[arr.length-1].replace('.html','');


        // 將當前的頁面對應的key值的a元素設置active的class
        $('a.'+page).addClass('active');
    }

    init();
    

})();

美食列表

(function(){

    // 商家詳情模版字元串
    var itemTmpl = '<div class="r-item-content">'+
                        '<img class="item-img" src=$pic_url />'+
                        '$brand'+
                        '<div class="item-info-content">'+
                            '<p class="item-title">$name</p>'+
                            '<div class="item-desc clearfix">'+
                                '<div class="item-score">$wm_poi_score</div>'+
                                '<div class="item-count">月售$monthNum</div>'+
                                '<div class="item-distance">&nbsp;$distance</div>'+
                                '<div class="item-time">$mt_delivery_time&nbsp;|</div>'+
                            '</div>'+
                            '<div class="item-price">'+
                                '<div class="item-pre-price">$min_price_tip</div>'+
                            '</div>'+
                            '<div class="item-others">'+
                                '$others'+
                            '</div>'+
                        '</div>'+
                    '</div>';

    var page = 0;
    var isLoading = false;
    /** 
    *  獲取商家列表數據
    *  param 
    */
    function getList(){
        page++;
        isLoading = true;
        $.get('../json/homelist.json', function(data){

            console.log(data);
            var list = data.data.poilist || [];

            initContentList(list);
            isLoading = false;
            
        });
    }

    /** 
    *  渲染是否時新到熱門品牌標簽
    *  param {} data
    */
    function getBrand(data){
        if (data.brand_type) {
            return '<div class="brand brand-pin">品牌</div>';
        } else {
            return '<div class="brand brand-xin">新到</div>';
        }
    }

    /** 
    *  渲染月售
    *  param {} data
    */
    function getMonthNum(data){
        var num = data.month_sale_num;

        // 大於999採用999+
        if (num > 999) {
            return '999+';
        }

        return num
    }

    /** 
    *  渲染商家活動
    *  param {} data
    */
    function getOthers(data){

        var array = data.discounts2;

        var str = '';

        array.forEach(function(item, index){

            // 內部的商家活動模版字元串
            var _str = '<div class="other-info">'+
                           '<img src=$icon_url class="other-tag" />'+
                           '<p class="other-content one-line">$info</p>'+
                        '</div>';


            // 模版字元串替換數據
            _str = _str.replace('$icon_url',item.icon_url)
                        .replace('$info', item.info);


            // 字元串拼接
            str = str + _str;
        })

        return str;
    }

    /** 
    *  渲染列表數據
    *  param []
    */
    function initContentList(list){
        list.forEach(function(item, index){
            var str = itemTmpl
                      .replace('$pic_url',item.pic_url)
                      .replace('$name',item.name)
                      .replace('$distance',item.distance)
                      .replace('$min_price_tip',item.min_price_tip)
                      .replace('$mt_delivery_time',item.mt_delivery_time)

                      .replace('$brand',getBrand(item))

                      .replace('$monthNum',getMonthNum(item))

                      .replace('$others',getOthers(item))

                      .replace('$wm_poi_score', new StarScore(item.wm_poi_score).getStars())
                      

            $('.list-wrap').append($(str));
        })

    }


    function addEvent(){
        window.addEventListener('scroll',function(){
            var clientHeight = document.documentElement.clientHeight;
            var scrollHeight = document.body.scrollHeight;
            var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;

            var proDis = 30;
            if ((scrollTop + clientHeight) >= (scrollHeight-proDis)) {
                

                // 最多滾動載入3頁
                if (page < 3) {

                    // 在發送ajax請求時避免觸發多次滾動載入
                    if (isLoading) {
                        return;
                    }
                    getList();
                }else {
                    $('.loading').text('載入完成');
                }

                
            }
        });
    }




    function init() {
        getList();
        addEvent();
    }

    init();
})();

首頁搞定!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 閉包 閉包的概念: 函數A中, 有一個函數B, 函數B中可以訪問函數A中定義的變數或者是數據, 此時形成了閉包(這句話暫時不嚴謹) 閉包的模式: 函數模式的閉包, 對象模式的閉包 閉包的作用: 緩存數據, 延長作用域鏈 閉包的優點和缺點: 緩存數據 閉包的應用 函數模式的閉包: 在一個函數中有一個函 ...
  • WARNING: Make sure that .NET Framework 4.5 or later and Powershell 3 or later are installed, otherwise extracting the Electron zip file will hang. ...
  • 作用域,作用域鏈和預解析 變數 >局部變數和全局變數, 作用域: 就是變數的使用範圍 局部作用域和全局作用域 js中沒有塊級作用域 一對括弧中定義的變數,這個變數可以在大括弧外面使用 函數中定義的變數是局部變數 while (true) { var num = 10; break; } consol ...
  • 函數作為返回值使用拓展,排序 排序, 每個文件都有名字,大小,時間,都可以按照某個屬性的值進行排序 函數作為返回值 函數作為參數 //排序,每個文件都有名字,大小,時間,都可以按照某個屬性的值進行排序 //三部電影,電影有名字,大小,上映時間 function File(name, size, ti ...
  • 函數作為參數使用 var arr = [1, 100, 20, 200, 40, 50, 120, 10]; //排序 arr.sort(); console.log(arr); 排序 函數作為參數使用, 匿名函數作為sort方法的參數使用, 那麼此時的匿名函數中有兩個參數 var arr = [1 ...
  • 函數作為返回值使用 function f1() { console.log("f1函數開始"); return function () { console.log("函數作為返回值使用"); } } 獲取num這個變數的數據類型 num 判斷這個對象是不是某個類型的 var num = 10; co ...
  • 項目圖 首先是menu.html <!DOCTYPE html> <html> <head> <title>深圳麥當勞前海二餐廳</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, ini ...
  • 項目整體圖 首先是order.html <!DOCTYPE html> <html> <head> <title>訂單</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial- ...
一周排行
    -Advertisement-
    Play Games
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...