效果图

首先是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

专门建立的学习Q-q-u-n: 784783012 ,分享学习的方法和需要注意的小细节,不停更新最新的教程和学习技巧
(从零基础开始到前端项目实战教程,学习工具,全栈开发学习路线以及规划)
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();
})();
专门建立的学习Q-q-u-n: 784783012 ,分享学习的方法和需要注意的小细节,不停更新最新的教程和学习技巧
(从零基础开始到前端项目实战教程,学习工具,全栈开发学习路线以及规划)

首页搞定!


程序员阿宇
3.2k 声望791 粉丝

前端学习交流群:784783012 欢迎新手,进阶者