[TOC]
## 步驟 1 : homePage.jsp 的復雜性
在homePage中要顯示如下內容
1 天貓超市連接右側有4個分類數據
2 豎狀導航欄顯示17個分類數據
3 每個分類又再對應不同的推薦產品集合
4 中部會顯示17個分類
5 每個分類又顯示前5款產品
6 每款產品又會顯示第一張圖片,標題,價格等信息
倘若把這些功能都在一個jsp中開發出來看,那么這個jsp就會變得非常的長,并且難以維護和擴展。在這里,就可以借鑒home.jsp的思路,把一個大的頁面,拆成各個小的jsp,這樣維護起來就相對容易了
項目頁面結構圖:

## 步驟 2 : homePage.jsp 所包含頁面關系
1. categoryAndcarousel.jsp
分類和輪播
1.1 categoryMenu.jsp
豎狀分類菜單
1.2 productsAsideCategorys.jsp
豎狀分類菜單右側的推薦產品列表
1.3 carousel.jsp
輪播
2. homepageCategoryProducts.jsp
總體17種分類以及每種分類對應的5個產品

## 步驟 3 : categoryAndcarousel.jsp
categoryAndcarousel.jsp 頁面利用ForeController傳遞過來的數據,天貓國際幾個字旁邊顯示4個分類超鏈
另外包含了其他3個頁面:
categoryMenu.jsp
productsAsideCategorys.jsp
carousel.jsp
這3個頁面在接下來的步驟就會講到
### 貓耳朵效果講解
首先看下面的css, 這是用來使得貓耳朵圖片隱藏并且是絕對定位狀態
~~~
img.catear {
position: absolute;
height: 15px;
display: none;
}
~~~
監聽菜單鼠標移入事件mouseenter,當鼠標移入的時候,獲取當前span的左,上和寬度信息,根據這些信息,計算出貓耳朵應該出現的位置,然后通過css設置貓耳朵的left和top數據, 最后使用fadeIn(500),在半秒內淡入貓耳朵圖片。
~~~
$("div.rightMenu span").mouseenter(function(){
var left = $(this).position().left;
var top = $(this).position().top;
var width = $(this).css("width");
var destLeft = parseInt(left) + parseInt(width)/2;
$("img#catear").css("left",destLeft);
$("img#catear").css("top",top-20);
$("img#catear").fadeIn(500);
});
~~~
當鼠標移出的時候,隱藏貓耳朵
~~~
$("div.rightMenu span").mouseleave(function(){
$("img#catear").hide();
});
~~~
### 顯示和隱藏效果講解
左側的菜單項div的class是eachCategory
`<div class="eachCategory" cid="83">`
右側的產品列表div的class是productsAsideCategorys
`<div class="productsAsideCategorys" cid="83" style="display: none;">`
首先每個菜單項eachCategory都有一個cid屬性,取的是該分類的id值
然后這個菜單項對應的產品列表,也有一個一樣的cid屬性。
整體思路是:
1. 把所有的產品列表都隱藏
2. 當鼠標移動到菜單項上的時候,取出對應的cid
3. 根據cid,找到對應的產品列表
4. 顯示該產品列表
5. 當鼠標移開的時候,隱藏對應的產品列表
顯示產品列表函數
~~~
function showProductsAsideCategorys(cid){
$("div.eachCategory[cid="+cid+"]").css("background-color","white");
$("div.eachCategory[cid="+cid+"] a").css("color","#87CEFA");
$("div.productsAsideCategorys[cid="+cid+"]").show();
}
~~~
隱藏產品列表函數
~~~
function hideProductsAsideCategorys(cid){
$("div.eachCategory[cid="+cid+"]").css("background-color","#e2e2e3");
$("div.eachCategory[cid="+cid+"] a").css("color","#000");
$("div.productsAsideCategorys[cid="+cid+"]").hide();
}
~~~
當鼠標移入菜單項的時候,顯示對應的產品列表
~~~
$("div.eachCategory").mouseenter(function(){
var cid = $(this).attr("cid");
showProductsAsideCategorys(cid);
});
~~~
當鼠標移出菜單項的時候,隱藏對應的產品列表
~~~
$("div.eachCategory").mouseleave(function(){
var cid = $(this).attr("cid");
hideProductsAsideCategorys(cid);
});
~~~
當鼠標移入產品列表的時候,顯示對應的產品列表
~~~
$("div.productsAsideCategorys").mouseenter(function(){
var cid = $(this).attr("cid");
showProductsAsideCategorys(cid);
});
~~~
當鼠標移出產品列表的時候,隱藏對應的產品列表
~~~
$("div.productsAsideCategorys").mouseleave(function(){
var cid = $(this).attr("cid");
hideProductsAsideCategorys(cid);
});
~~~
homePage.jsp:
```
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<script>
/* 顯示產品列表函數 */
function showProductsAsideCategorys(cid) {
/* 選擇class是eachCategory,屬性cid值的某個cid具體值的div, 把背景色修改成白色 */
$("div.eachCategory[cid=" + cid + "]").css("background-color", "white");
/* 選擇class是eachCategory,屬性cid值的某個cid具體值的div 下面的超鏈, 把顏色修改成#87CEFA */
$("div.eachCategory[cid=" + cid + "] a").css("color", "#87CEFA");
/* 選擇class是productsAsideCategorys,屬性cid值的某個cid具體值的div ,顯示出來 */
$("div.productsAsideCategorys[cid=" + cid + "]").show();
}
/* 隱藏產品列表函數 */
function hideProductsAsideCategorys(cid) {
$("div.eachCategory[cid=" + cid + "]").css("background-color",
"#e2e2e3");
$("div.eachCategory[cid=" + cid + "] a").css("color", "#000");
$("div.productsAsideCategorys[cid=" + cid + "]").hide();
}
$(function() {
/* 當鼠標移入菜單項的時候,顯示對應的產品列表 */
$("div.eachCategory").mouseenter(function() {
var cid = $(this).attr("cid");
showProductsAsideCategorys(cid);
});
/* 當鼠標移出菜單項的時候,隱藏對應的產品列表 */
$("div.eachCategory").mouseleave(function() {
var cid = $(this).attr("cid");
hideProductsAsideCategorys(cid);
});
/* 當鼠標移入產品列表的時候,顯示對應的產品列表 */
$("div.productsAsideCategorys").mouseenter(function() {
var cid = $(this).attr("cid");
showProductsAsideCategorys(cid);
});
/* 當鼠標移出產品列表的時候,隱藏對應的產品列表 */
$("div.productsAsideCategorys").mouseleave(function() {
var cid = $(this).attr("cid");
hideProductsAsideCategorys(cid);
});
/* 監聽菜單鼠標移入事件,計算貓耳朵顯示位置 */
$("div.rightMenu span").mouseenter(function() {
var left = $(this).position().left;
var top = $(this).position().top;
var width = $(this).css("width");
var destLeft = parseInt(left) + parseInt(width) / 2;
$("img#catear").css("left", destLeft);
$("img#catear").css("top", top - 20);
$("img#catear").fadeIn(500);
});
/* 鼠標移出的時候,隱藏貓耳朵 */
$("div.rightMenu span").mouseleave(function() {
$("img#catear").hide();
});
/* 根據輪播圖的位置,設定分類菜單,產品列表等的距離 */
var left = $("div#carousel-of-product").offset().left;
$("div.categoryMenu").css("left", left - 20);
$("div.categoryWithCarousel div.head").css("margin-left", left);
$("div.productsAsideCategorys").css("left", left - 20);
});
</script>
<img src="img/site/catear.png" id="catear" class="catear" />
<div class="categoryWithCarousel">
<div class="headbar">
<div class="head ">
<span style="margin-left: 10px" class="glyphicon glyphicon-th-list"></span> <span style="margin-left: 10px">商品分類</span>
</div>
<div class="rightMenu">
<span><a href=""><img src="img/site/chaoshi.png" /></a></span> <span><a href=""><img src="img/site/guoji.png" /></a></span>
<c:forEach items="${cs}" var="c" varStatus="st">
<c:if test="${st.count<=4}">
<span> <a href="forecategory?cid=${c.id}"> ${c.name} </a></span>
</c:if>
</c:forEach>
</div>
</div>
<div style="position: relative">
<!-- 分類列表 -->
<%@include file="categoryMenu.jsp"%>
</div>
<div style="position: relative; left: 0; top: 0;">
<!-- 分類列表左側產品列表 -->
<%@include file="productsAsideCategorys.jsp"%>
</div>
<!-- 輪播圖 -->
<%@include file="carousel.jsp"%>
<div class="carouselBackgroundDiv"></div>
</div>
```
## 步驟 4 : categoryMenu.jsp
categoryMenu.jsp 顯示左側的豎狀分類導航

~~~
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<div class="categoryMenu">
<c:forEach items="${cs}" var="c">
<div cid="${c.id}" class="eachCategory">
<span class="glyphicon glyphicon-link"></span>
<a href="forecategory?cid=${c.id}">
${c.name}
</a>
</div>
</c:forEach>
</div>
~~~
## 步驟 5 : productsAsideCategorys.jsp
productsAsideCategorys.jsp 進行了三層遍歷
1. 先取出每個分類
2. 然后取出每個分類的productsByRow集合
3. 根據productsByRow集合,取出每個產品,把產品的subTitle信息里的第一個單詞取出來顯示。
JQuery代碼解釋:
> 這個是用于隨機挑選一個產品作為推薦產品,來進行高亮顯示。 嚴格的說,應該是后臺設置那個產品是推薦產品,這里不做那么復雜,直接在前端按照20%的概率,隨機挑選了一個產品。
~~~
$("div.productsAsideCategorys div.row a").each(function(){
var v = Math.round(Math.random() *4);
if(v == 1)
$(this).css("color","#87CEFA");
});
~~~

~~~
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<script>
$(function(){
$("div.productsAsideCategorys div.row a").each(function() {
var v = Math.round(Math.random() *4);
if(v == 1) {
$(this).css("color","#87CEFA");
}
});
});
</script>
<c:forEach items="${cs}" var="c">
<div cid="${c.id}" class="productsAsideCategorys">
<c:forEach items="${c.productsByRow}" var="ps">
<div class="row">
<c:forEach items="${ps}" var="p">
<c:if test="${!empty p.subTitle}">
<a href="foreproduct?pid=${p.id}">
<c:forEach items="${fn:split(p.subTitle, ' ')}" var="title" varStatus="st">
<c:if test="${st.index==0}">
${title}
</c:if>
</c:forEach>
</a>
</c:if>
</c:forEach>
<div class="seperator"></div>
</div>
</c:forEach>
</div>
</c:forEach>
~~~
> 拓展資料
> fn標簽提供各種實用功能,首先使用之前使用加入如下指令
> `<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> `
>
> fn:split(string, separator)
> 返回一個數組,以參數separator 為分割符分割參數string,分割后的每一部分就是數組的一個元素
> 當然也可在后臺Java代碼,即service中實現。
## 步驟 6 : carousel.jsp
輪播部分,都是靜態的頁面,沒有用到服務端數據

~~~
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<div id="carousel-of-product" class="carousel-of-product carousel slide1" data-ride="carousel">
<!-- 指示符 -->
<ol class="carousel-indicators">
<li data-target="#carousel-of-product" data-slide-to="0" class="active"></li>
<li data-target="#carousel-of-product" data-slide-to="1"></li>
<li data-target="#carousel-of-product" data-slide-to="2"></li>
<li data-target="#carousel-of-product" data-slide-to="3"></li>
</ol>
<!-- 輪播圖片 -->
<div class="carousel-inner" role="listbox">
<div class="item active">
<img class="carousel carouselImage" src="img/lunbo/1.jpg">
</div>
<div class="item">
<img class="carouselImage" src="img/lunbo/2.jpg">
</div>
<div class="item">
<img class="carouselImage" src="img/lunbo/3.jpg">
</div>
<div class="item">
<img class="carouselImage" src="img/lunbo/4.jpg">
</div>
</div>
<!-- 左右切換按鈕 -->
<!-- <a class="left carousel-control" href="#carousel-of-product" role="button" data-slide="prev"> -->
<!-- <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> -->
<!-- </a> -->
<!-- <a class="right carousel-control" href="#carousel-of-product" role="button" data-slide="next"> -->
<!-- <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> -->
<!-- </a> -->
</div>
~~~
## 步驟 7 : homepageCategoryProducts.jsp
homepageCategoryProducts.jsp 進行了2次遍歷
1. 遍歷所有的分類,取出每個分類對象
2. 遍歷分類對象的products集合,取出每個產品,然后顯示該產品的標題,圖片,價格等信息

~~~
<!DOCTYPE html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix='fmt' uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<div class="homepageCategoryProducts">
<c:forEach items="${cs}" var="c" varStatus="stc">
<div class="eachHomepageCategoryProducts">
<div class="left-mark"></div>
<span class="categoryTitle">${c.name}</span>
<br>
<c:forEach items="${c.products}" var="p" varStatus="st">
<c:if test="${st.count<=5}">
<div class="productItem" >
<a href="foreproduct?pid=${p.id}"><img width="100px" src="img/productSingle_middle/${p.firstProductImage.id}.jpg"></a>
<a class="productItemDescLink" href="foreproduct?pid=${p.id}">
<span class="productItemDesc">[熱銷]
${fn:substring(p.name, 0, 20)}
</span>
</a>
<span class="productPrice">
<fmt:formatNumber type="number" value="${p.promotePrice}" minFractionDigits="2"/>
</span>
</div>
</c:if>
</c:forEach>
<div style="clear:both"></div>
</div>
</c:forEach>
<img id="endpng" class="endpng" src="img/site/end.png">
</div>
~~~
> fn:substring()函數返回字符串中指定開始和結束索引的子串。意思是取產品名字的前20個字符
>
### 拓展資料: fmt:formatNumber 格式化數字
> fmt 標簽常用來進行格式化,其中fmt:formatNumber用于格式化數字
使用之前要加上
`<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix='fmt' %> `
`<fmt:formatNumber type="number" value="${money}" minFractionDigits="2"/>`
<fmt:formatNumber 表示格式化數字
minFractionDigits 小數點至少要有的位數
maxFractionDigits 小數點最多能有的位數
## 步驟 8 : 總結
雖然首頁顯示的內容非常多,可以說是前端里最復雜的一個展示頁面,但是通過這種拆成小塊jsp的思路,每個jsp頁面的功能就相對單一了。 可以更好的幫助大家理解。
- 項目簡介
- 功能一覽
- 前臺
- 后臺
- 開發流程
- 需求分析-展示
- 首頁
- 產品頁
- 分類頁
- 搜索結果頁
- 購物車查看頁
- 結算頁
- 確認支付頁
- 支付成功頁
- 我的訂單頁
- 確認收貨頁
- 確認收貨成功頁
- 評價頁
- 需求分析-交互
- 分類頁排序
- 立即購買
- 加入購物車
- 調整訂單項數量
- 刪除訂單項
- 生成訂單
- 訂單頁功能
- 確認付款
- 確認收貨
- 提交評價信息
- 登錄
- 注冊
- 退出
- 搜索
- 前臺需求列表
- 需求分析后臺
- 分類管理
- 屬性管理
- 產品管理
- 產品圖片管理
- 產品屬性設置
- 用戶管理
- 訂單管理
- 后臺需求列表
- 表結構設計
- 數據建模
- 表與表之間的關系
- 后臺-分類管理
- 可運行的項目
- 靜態資源
- JSP包含關系
- 查詢
- 分頁
- 增加
- 刪除
- 編輯
- 修改
- 做一遍
- 重構
- 分頁方式
- 分類逆向工程
- 所有逆向工程
- 后臺其他頁面
- 屬性管理實現
- 產品管理實現
- 產品圖片管理實現
- 產品屬性值設置
- 用戶管理實現
- 訂單管理實現
- 前端
- 前臺-首頁
- 可運行的項目
- 靜態資源
- ForeController
- home方法
- home.jsp
- homePage.jsp
- 前臺-無需登錄
- 注冊
- 登錄
- 退出
- 產品頁
- 模態登錄
- 分類頁
- 搜索
- 前臺-需要登錄
- 購物流程
- 立即購買
- 結算頁面
- 加入購物車
- 查看購物車頁面
- 登錄狀態攔截器
- 其他攔截器
- 購物車頁面操作
- 訂單狀態圖
- 生成訂單
- 我的訂單頁
- 我的訂單頁操作
- 評價產品
- 總結