项目图

首先是menu.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" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
</head>
<body>
<!--头部开始-->
<div class="nav">
<div class="back-icon"></div>
<h4 class="title">深圳麦当劳前海二餐厅</h4>
</div>
<!--头部结束-->
<!--tabbar开始-->
<div class="tab-bar">
</div>
<!--tabbar结束-->
<!--点菜内容区开始-->
<div class="menu-inner">
<div class="left-bar">
<div class="left-bar-inner"></div>
</div>
<div class="right-content">
<p class="right-title"></p>
<div class="right-list">
<div class="right-list-inner"></div>
</div>
</div>
<!--购物车区域开始-->
<div class="shop-bar"></div>
<div class="mask hide"></div>
<!--购物车区域结束-->
</div>
<!--点菜内容区结束-->
<script type="text/javascript" src="../lib/jquery.min.js"></script>
<script rel="stylesheet" type="text/javascript" src="../common/headertab/headertab.js"></script>
<script rel="stylesheet" type="text/javascript" src="./left/left.js"></script>
<script rel="stylesheet" type="text/javascript" src="./right/right.js"></script>
<script rel="stylesheet" type="text/javascript" src="./shopbar/shopbar.js"></script>
</body>
</html>
css部分 reset.css跟之前一样
顶部样式 navheader.css
.nav {
height: 1.706667rem;
border-bottom: 1px solid #b2b2b2;
position: fixed;
width: 100%;
top: 0;
z-index: 99;
background-color: #fff;
}
.nav .title {
font-size: 0.453333rem;
color: #2f2f2f;
text-align: center;
line-height: 1.946667rem;
}
.nav .back-icon {
width: 0.72rem;
height: 0.72rem;
position: absolute;
top: 0.613333rem;
left: 0.32rem;
background-image: url('./img/back.png');
background-size: cover;;
}
tab导航切换样式 headertab.css
.tab-bar {
font-size: 0.426667rem;
display: flex;
border-bottom: 1px solid #f0f0f0;
margin-top: 1.706667rem;
}
.tab-bar .tab-item {
flex: 1;
height: 1.2rem;
line-height: 1.2rem;
position: relative;
color: #666;
text-align: center;
text-decoration: none;
}
.tab-bar .tab-item.active::after {
content: ' ';
display: block;
height: 0.106667rem;
width: 1.6rem;
position: absolute;
bottom: 0;
background-color: #ffd161;
left: 50%;
transform: translatex(-50%);
-webkit-transform: translatex(-50%);
}
左侧导航样式 left.css
.menu-inner {
position: absolute;
right: 0;
bottom: 0;
top: 2.933333rem;
left: 0;
display: flex;
overflow: hidden;
}
.menu-inner .left-bar {
width: 2.266667rem;
background-color: #efefef;
overflow: auto;
height: 100%;
-webkit-overflow-scrolling: touch;
}
.menu-inner .left-bar-inner {
padding-bottom: 2.266667rem;
}
.menu-inner .left-item {
font-size: 0.373333rem;
color: #656565;
text-align: center;
border-bottom: 1px solid #bfbfbf;
display: flex;
height: 1.6rem;
justify-content: center;
}
.menu-inner .left-item.active {
background-color: #fff;
}
.menu-inner .item-text {
text-align: center;
align-self: center;
}
.menu-inner .item-icon {
width: 0.533333rem;
height: 0.533333rem;
display: inline-block;
margin-right: 0.16rem;
vertical-align: -0.106667rem;
}
右侧详情区域样式 right.css
.right-content {
flex: 1;
margin-left: 0.266667rem;
height: 100%;
overflow: hidden;
-webkit-overflow-scrolling: touch;
}
.right-content .right-list {
height: 100%;
overflow: auto;
}
.right-content .right-list-inner {
font-size: 0.426667rem;
padding-bottom: 2.266667rem;
}
.right-content .right-title {
font-size: 0.346667rem;
color: #333;
margin-top: 0.266667rem;
padding-left: 0.106667rem;
border-left: 0.053333rem solid #ffd161;
}
.right-content .menu-item {
display: flex;
padding-top: 0.666667rem;
padding-bottom: 0.666667rem;
border-bottom: 1px solid #f0f0f0;
position: relative;
}
.right-content .menu-item .img {
width: 1.653333rem;
height: 1.653333rem;
margin-right: 0.266667rem;
}
.right-content .menu-item-right {
flex: 1;
}
.right-content .item-title {
font-size: 0.426667rem;
color: #2f2f2f;
}
.item-zan,.item-desc {
color: #a9a9a9;
font-size: 0.32rem;
margin-top: 0.16rem;
line-height: 0.373333rem;
padding-right: 0.106667rem;
}
.right-content .menu-item-right .item-desc {
line-height: 0.453333rem;
}
.right-content .item-price {
margin-top: 0.266667rem;
color: #fe4d3d;
font-size: 0.48rem;
}
.right-content .unit {
color: #a9a9a9;
font-size: 0.32rem;
}
.right-content .select-content {
position: absolute;
right: 0.24rem;
bottom: 0.56rem;
display: flex;
}
.right-content .plus {
width: 0.666667rem;
height: 0.666667rem;
background-image: url('./img/plus.png');
background-size: cover;
}
.right-content .minus {
width: 0.666667rem;
height: 0.666667rem;
background-image: url('./img/minus.png');
background-size: cover;
}
.right-content .count {
font-size: 0.4rem;
color: #2f2f2f;
width: 0.666667rem;
height: 0.666667rem;
line-height: 0.666667rem;
margin-left: 0.053333rem;
margin-right: 0.053333rem;
text-align: center;
}
购物车区域样式 shopbar.css
.shop-bar {
position: absolute;
bottom: 0;
left: 0;
right: 0;
z-index: 99;
}
.shop-bar .bottom-content {
height: 1.333333rem;
display: flex;
background-color: rgba(51,51,51,0.9);
}
.shop-bar .shop-icon {
width: 1.466667rem;
height: 1.466667rem;
background-image: url('./img/shop-icon.png');
background-size: cover;
margin-top: -0.4rem;
margin-left: 0.32rem;
position: relative;
}
.shop-bar .price-content {
flex: 1;
padding-top: 0.213333rem;
padding-left: 0.186667rem;
}
.shop-bar .total-price {
font-size: 0.533333rem;
color: #fff;
}
.shop-bar .other-price {
font-size: 0.32rem;
color: #999;
margin-top: 0.053333rem;
}
.shop-bar .dot-num {
position: absolute;
background-color: #fb4e44;
width: 0.4rem;
height: 0.4rem;
font-size: 0.32rem;
color: #fff;
border: 1px solid #fff;
border-radius: 50%;
right: 0;
top: 0.053333rem;
text-align: center;
line-height: 0.4rem;
}
.shop-bar .submit-btn {
width: 2.933333rem;
height: 100%;
background-color: #ffd161;
color: #333;
font-size: 0.426667rem;
line-height: 1.333333rem;
text-align: center;
}
.choose-content {
background-color: #fff;
}
.choose-content .content-top {
height: 0.933333rem;
background-color: #f4f4f4;
font-size: 0.293333rem;
display: flex;
align-items: center;
justify-content: flex-end;
}
.choose-content .clear-car {
margin-left: 0.266667rem;
margin-right: 0.133333rem;
float: left;
position: relative;
}
.choose-content .clear-car::after {
content: ' ';
width: 0.346667rem;
height: 0.346667rem;
display: block;
background-image: url('./img/clear.jpeg');
background-size: cover;
position: absolute;
top: -0.026667rem;
left: -0.373333rem;
}
.choose-content .choose-item {
display: flex;
font-size: 0.4rem;
color: #2f2f2f;
height: 0.933333rem;
align-items: center;
padding-top: 0.266667rem;
padding-bottom: 0.266667rem;
border-bottom: 1px solid #ddd;
}
.choose-content .choose-item .price {
margin-left: 0.133333rem;
margin-right: 0.666667rem;
}
.choose-content .choose-item .item-name {
flex: 1;
padding-left: 0.266667rem;
}
.choose-content .select-content {
position: relative;
margin-right: 0.213333rem;
display: flex;
}
.choose-content .plus {
width: 0.666667rem;
height: 0.666667rem;
background-image: url('./img/plus.png');
background-size: cover;
}
.choose-content .minus {
width: 0.666667rem;
height: 0.666667rem;
background-image: url('./img/minus.png');
background-size: cover;
}
.choose-content .count {
font-size: 0.4rem;
color: #2f2f2f;
width: 0.666667rem;
height: 0.666667rem;
line-height: 0.666667rem;
margin-left: 0.053333rem;
margin-right: 0.053333rem;
text-align: center;
}
.mask {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
background-color: rgba(0,0,0,0.7);
}
然后是js文件
tab导航切换 headertab.js
(function(){
var itemtmpl = '<a class="$key tab-item" >'+
'$text'+
'</a>'
function init(){
var items = [{
key: 'menu',
text: '点菜'
},{
key: 'comment',
text: '评价'
},{
key: 'restanurant',
text: '商家'
}];
var str = '';
items.foreach(function(item){
str += itemtmpl.replace(/\$key/g,item.key)
.replace('$text',item.text)
});
$('.tab-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();
})();
左侧导航 left.js
(function(){
// 左侧类目item模版字符串
var itemtmpl = '<div class="left-item">'+
'<div class="item-text">$getitemcontent'+
'</div>';
/**
* 请求数据
* param
*/
function getlist(){
$.get('../json/food.json', function(data){
console.log(data);
window.food_spu_tags = data.data.food_spu_tags || [];
initcontentlist(window.food_spu_tags);
window.shopbar.changeshippingprice(data.data.poi_info.shipping_fee || 0);
})
}
/**
* 渲染item内容
* param obj
*/
function getitemcontent(data){
if (data.icon) {
return '<img class="item-icon" src='+data.icon+' />'+data.name;
} else {
return data.name;
}
}
/**
* 渲染列表
* param array
*/
function initcontentlist(list){
list.foreach(function(item, index){
var str = itemtmpl.
replace('$getitemcontent', getitemcontent(item));
// 将item数据挂载到left-item上面
var $target = $(str);
$target.data('itemdata',item);
$('.left-bar-inner').append($target);
})
$('.left-item').first().click();
}
function addclick(){
$('.menu-inner').on('click', '.left-item', function(e){
var $target = $(e.currenttarget);
$target.addclass('active');
$target.siblings().removeclass('active');
// 将数据传给右侧详情列表进行渲染
window.right.refresh($target.data('itemdata'));
});
}
function init(){
getlist();
addclick();
}
init();
})();
右侧详情 right.js
(function(){
// 右侧类目item模版字符串
var itemtmpl = '<div class="menu-item">'+
'<img class="img" src=$picture />'+
'<div class="menu-item-right">'+
'<p class="item-title">$name</p>'+
'<p class="item-desc">$description</p>'+
'<p class="item-zan">$praise_content</p>'+
'<p class="item-price">¥$min_price<span class="unit">/$unit</span></p>'+
'</div>'+
'<div class="select-content">'+
'<div class="minus"></div>'+
'<div class="count">$choosecount</div>'+
'<div class="plus"></div>'+
'</div>'+
'</div>';
/**
* 渲染列表
* param array
*/
function initrightlist(list){
$('.right-list-inner').html('');
list.foreach(function(item, index){
if (!item.choosecount) {
item.choosecount = 0;
}
var str = itemtmpl.
replace('$picture', item.picture).
replace('$name', item.name).
replace('$description', item.description).
replace('$praise_content', item.praise_content).
replace('$min_price', item.min_price).
replace('$unit', item.unit).
replace('$choosecount', item.choosecount);
var $target = $(str);
$target.data('itemdata',item);
$('.right-list-inner').append($target);
})
}
/**
* 渲染右侧title
* param string
*/
function initrighttitle(str){
$('.right-title').text(str);
}
function addclick(){
$('.menu-item').on('click', '.plus', function(e){
var $count = $(e.currenttarget).parent().find('.count');
$count.text(parseint($count.text()||'0')+1);
var $item = $(e.currenttarget).parents('.menu-item').first();
var itemdata = $item.data('itemdata');
itemdata.choosecount = itemdata.choosecount + 1;
window.shopbar.renderitems();
});
$('.menu-item').on('click', '.minus', function(e){
var $count = $(e.currenttarget).parent().find('.count');
if ($count.text() == 0) return;
$count.text(parseint($count.text()||'0')-1);
var $item = $(e.currenttarget).parents('.menu-item').first();
var itemdata = $item.data('itemdata');
itemdata.choosecount = itemdata.choosecount - 1;
window.shopbar.renderitems();
});
}
function init(data){
initrightlist(data.spus || []);
initrighttitle(data.name);
addclick();
}
window.right = {
refresh: init
}
})();
购物车区域 shopbar.js
(function(){
// 顶部模版字符串
var itemtoptmpl = '<div class="choose-content hide">'+
'<div class="content-top">'+
'<div class="clear-car">清空购物车</div>'+
'</div>'+
'</div>';
// 底部模版字符串
var itembottomtmpl = '<div class="bottom-content">'+
'<div class="shop-icon">'+
'<div class="dot-num hide"></div>'+
'</div>'+
'<div class="price-content">'+
'<p class="total-price">¥<span class="total-price-span">0</span></p>'+
'<p class="other-price">另需配送 ¥<span class="shipping-fee">0</span></p>'+
'</div>'+
'<div class="submit-btn">去结算</div>'+
'</div>';
var $strbottom = $(itembottomtmpl);
var $strtop = $(itemtoptmpl);
function changeshippingprice(str){
$strbottom.find('.shipping-fee').text(str);
}
function changetotalprice(str){
$strbottom.find('.total-price-span').text(str);
}
/**
* 渲染购物车顶部
* param
*/
function renderitems(){
$strtop.find('.choose-item').remove();
var list = window.food_spu_tags || [];
var tmpl = '<div class="choose-item">'+
'<div class="item-name">$name</div>'+
'<div class="price">¥<span class="total">$price</span></div>'+
'<div class="select-content">'+
'<div class="minus"></div>'+
'<div class="count">$choosecount</div>'+
'<div class="plus"></div>'+
'</div>';
var totalprice = 0;
list.foreach(function(item){
item.spus.foreach(function(_item){
// 如果有菜品数量大于0就开始渲染这条数据
if (_item.choosecount > 0) {
// 计算每个菜品的总价 就是 单价*数量
var price = _item.min_price*_item.choosecount;
var row = tmpl.replace('$name',_item.name)
.replace('$price',price)
.replace('$choosecount',_item.choosecount)
// 计算整个总价
totalprice += price;
var $row = $(row);
$row.data('itemdata',_item);
$strtop.append($row);
}
})
// 改变总价
changetotalprice(totalprice);
// 改变红点个数
changedot();
});
}
/**
* 渲染数量红点
* param
*/
function changedot(){
// 先拿到所有的counts
var $counts = $strtop.find('.count');
var total = 0;
// 遍历每个count 相加
for (var i = 0 ; i < $counts.length ; i++) {
total += parseint($($counts[i]).text());
}
if (total > 0) {
$('.dot-num').show().text(total)
} else {
$('.dot-num').hide();
}
}
function addclick(){
$('.shop-bar').on('click', '.shop-icon', function(){
$('.mask').toggle();
$strtop.toggle();
});
$strtop.on('click','.plus', function(e){
var $count = $(e.currenttarget).parent().find('.count');
$count.text(parseint($count.text()||'0')+1);
var $item = $(e.currenttarget).parents('.choose-item').first();
var itemdata = $item.data('itemdata');
itemdata.choosecount = itemdata.choosecount + 1;
renderitems();
// 找到当前的右侧详情的数据,进行联动
$('.left-item.active').click();
});
$strtop.on('click','.minus', function(e){
var $count = $(e.currenttarget).parent().find('.count');
if ($count.text() == 0) return;
$count.text(parseint($count.text()||'0')-1);
var $item = $(e.currenttarget).parents('.choose-item').first();
var itemdata = $item.data('itemdata');
itemdata.choosecount = itemdata.choosecount - 1;
renderitems();
// 找到当前的右侧详情的数据,进行联动
$('.left-item.active').click();
});
}
function init(data){
$('.shop-bar').append($strtop);
$('.shop-bar').append($strbottom);
addclick();
}
init();
window.shopbar = {
renderitems: renderitems,
changeshippingprice:changeshippingprice
}
})();
这部分好了,放下效果图


最后把个人页面也补上(这个项目里最简单的页面)
my.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" >
<link rel="stylesheet" type="text/css" >
<link rel="stylesheet" type="text/css" >
</head>
<body>
<div class="my">
<div class="header">
<img class="avatar" src="http://www.51sjk.com/Upload/Articles/1/0/270/270945_20210708050916213.png" />
<p class="nickname">美团小骑手 ></p>
</div>
<div class="content">
<ul class="items">
<li class="address">收货地址管理</li>
<li class="money">商家代金券</li>
</ul>
<ul class="items">
<li class="email">意见反馈</li>
<li class="question">常见问题</li>
</ul>
<p class="tel">客服电话: 101-097-77</p>
<p class="time">服务时间: 9:00-23:00</p>
</div>
</div>
<!--底部栏开始-->
<div class="bottom-bar"></div>
<!--底部栏结束-->
<script type="text/javascript" src="../lib/jquery.min.js"></script>
<script type="text/javascript" src="../common/bottombar/bottombar.js"></script>
</body>
</html>
reset.css 和 bottombar.css 跟之前的一样
页面样式 my.css
.header {
width: 100%;
height: 4.266667rem;
background-image: url('./img/header.png');
background-size: cover;
overflow: hidden;
}
.avatar {
width: 1.92rem;
height: 1.92rem;
margin: 0 auto;
display: block;
border: 0.08rem solid rgba(255,255,255,0.4);
border-radius: 50%;
margin-top: 0.666667rem;
}
.nickname {
color: #333;
font-size: 0.426667rem;
text-align: center;
margin-top: 0.4rem;
}
.content {
min-height: 13.52rem;
background-color: #eee;
}
.items {
border-bottom: 0.266667rem solid #eee;
background-color: #fff;
}
.items li {
height: 1.2rem;
font-size: 0.373333rem;
position: relative;
padding-left: 0.693333rem;
margin-left: 0.4rem;
border-bottom: 1px solid #e4e4e4;
line-height: 1.2rem;
}
.items li::before {
content: ' ';
display: block;
width: 0.426667rem;
height: 0.426667rem;
position: absolute;
left: 0.026667rem;
background-size: cover;
top: 0.373333rem;
}
.items li::after {
content: '>';
display: block;
width: 0.426667rem;
height: 0.426667rem;
position: absolute;
top: 0;
right: 0.16rem;
color: #aaa;
}
.items li:last-child {
border: none;
}
.address::before {
background-image: url('./img/address.png');
}
.money::before {
background-image: url('./img/money.png');
}
.email::before {
background-image: url('./img/email.png');
}
.question::before {
background-image: url('./img/question.png');
}
.tel {
font-size: 0.4rem;
color: #ffb000;
text-align: center;
height: 1.226667rem;
line-height: 1.226667rem;
background-color: #fff;
}
.time {
font-size: 0.373333rem;
text-align: center;
margin-top: 0.346667rem;
color: #999;
}
bottombar.js 也跟之前的一样
效果图

不会耍帅的EZ