一、页面静态化介绍:

网页静态化解决方案在实际开发中运用比较多,例如新闻网站,门户网站中的新闻频道或者是文章类的频道。
image.png
对于电商网站的商品详细页来说,至少几百万个商品,每个商品又有大量的信息,这样的情况同样也适用于使用网页静态化来解决。
网页静态化技术和缓存技术的共同点都是为了减轻数据库的访问压力,但是具体的应用场景不同,缓存比较适合小规模的数据,而网页静态化比较适合大规模且相对变化不太频繁的数据。另外网页静态化还有利于SEO。
另外我们如果将网页以纯静态化的形式展现,就可以使用Nginx这样的高性能的web服务器来部署。Nginx可以承载5万的并发,而Tomcat只有几百。

二、如何实现页面静态化:

问题一:回顾一下前后端的交互顺序:

  1. 前端提交请求
  2. 请求被springMVC收到了,调用持久层查库,把数据放入model
  3. Thymeleaf把model里面的数据渲染到模板视图里面XXX.html
  4. 把渲染后的全部信息,全部写入到response里面

其实既然能写到response里面,就能写入到其他路径下,事实上,真的是这样做.

问题二:Thymeleaf如何把信息写入到response里? 做这件事的是ThymeleafAutoConfiguration里面的TemplateEngine模板引擎使用下面的方法 process(String template, IContext context, Writer writer)方法

他是如何做的呢?新认识几个概念
1 .Context 上下文

这是块共享的空间,处理用户的请求时,各个servlet可以共享,事实上当我们把数据放入Model ,springMvc就会把model放入Context

  1. TemplateResolver 模板解析器 ```java

@Bean public SpringResourceTemplateResolver defaultTemplateResolver() { SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver(); resolver.setApplicationContext(this.applicationContext); resolver.setPrefix(this.properties.getPrefix()); resolver.setSuffix(this.properties.getSuffix()); resolver.setTemplateMode(this.properties.getMode()); if (this.properties.getEncoding() != null) { resolver.setCharacterEncoding(this.properties.getEncoding().name()); } resolver.setCacheable(this.properties.isCache()); Integer order = this.properties.getTemplateResolverOrder(); if (order != null) { resolver.setOrder(order); } resolver.setCheckExistence(this.properties.isCheckTemplate()); return resolver;

  1. > 用来解析和读取配置文件,里面有我们的模拟的后缀以及路径,Thymeleaf的视图解析器依然是依赖它知道的配置信息,有了ContextTemplateResolver万事具备,只差渲染了,TemplateEngine调用process方法,模板引擎依靠context拿到数据,依靠templateResolver拿到配置信息,第三个参数是输出流,也就是我们的目标文件.
  2. 查看ThymeleafAutoConfiguration底层原码,可以看出,系统启动时会自动注入TemplateEngine<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/22202252/1628251221786-eabfe334-2c8a-4336-a35b-3f62c320b47b.png#clientId=u0e0497ad-54ca-4&from=paste&height=248&id=u4de5a243&margin=%5Bobject%20Object%5D&name=image.png&originHeight=495&originWidth=1519&originalType=binary&ratio=1&size=126326&status=done&style=none&taskId=u05bd6294-db56-4aa2-99a9-a79603a6593&width=759.5)
  3. <a name="xlO43"></a>
  4. ### 2.1 实现页面静态化:
  5. <a name="g9qFC"></a>
  6. #### 2.1.1 windows下安装nginx,如下图:
  7. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/22202252/1628251333507-01311b72-aa8d-458c-9f14-2f43a70e59bf.png#clientId=u0e0497ad-54ca-4&from=paste&height=242&id=uc6efd32f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=274&originWidth=844&originalType=binary&ratio=1&size=26269&status=done&style=shadow&taskId=uebd48cc9-2918-47fd-a316-338aefe848b&width=744)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/22202252/1628251370439-177fd04d-2bd1-478e-b17a-4185cd377c64.png#clientId=u0e0497ad-54ca-4&from=paste&height=223&id=u32ca081d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=257&originWidth=860&originalType=binary&ratio=1&size=18897&status=done&style=shadow&taskId=u4c1849b0-4ac3-42d4-a713-eda94020460&width=745)
  8. > 注:
  9. > 复制项目资料中的首页/中的静态资源到上图位置。
  10. <a name="F9tMm"></a>
  11. ### 2.2 新建工程zyg-page-interface与zyg-page-service
  12. > 注:
  13. > 按照正常流程创建。
  14. <a name="GOXgS"></a>
  15. #### 2.2.1 zyg-page-interface工程下的pom.xml文件:
  16. ```xml
  17. <dependencies>
  18. <dependency>
  19. <groupId>com.zelin</groupId>
  20. <artifactId>zyg-pojo</artifactId>
  21. <version>2.0</version>
  22. </dependency>
  23. </dependencies>

2.2.2 zyg-page-service工程下的pom.xml文件:

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-web</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.zelin</groupId>
  8. <artifactId>zyg-page-interface</artifactId>
  9. <version>2.0</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>com.zelin</groupId>
  13. <artifactId>zyg-dao</artifactId>
  14. <version>2.0</version>
  15. </dependency>
  16. <!--1. 引入thymeleaf-->
  17. <dependency>
  18. <groupId>org.springframework.boot</groupId>
  19. <artifactId>spring-boot-starter-thymeleaf</artifactId>
  20. </dependency>
  21. </dependencies>

2.2.3 zyg-page-service工程下的application.yml文件如下:

  1. server:
  2. port: 7004
  3. logging:
  4. level:
  5. com.zelin: debug
  6. spring:
  7. dubbo:
  8. application:
  9. name: zyg-page-service
  10. registry:
  11. address: zookeeper://192.168.56.10:2181
  12. base-package: com.zelin.page.service
  13. protocol:
  14. name: dubbo
  15. port: 21884
  16. thymeleaf:
  17. cache: false

2.2.4 复制项目资料首页下的item.html到zyg-page-service中的resources/templates目录下:

image.png

2.3 修改linux下的/mydata/nginx/conf/nginx.conf配置文件,添加上游服务器:

image.png

2.4 增加/mydata/nginx/conf/conf.d/zeyigou.conf如下配置:

  1. server {
  2. listen 80;
  3. server_name manager.zeyigou.com;
  4. location / {
  5. proxy_pass http://manager;
  6. proxy_set_header Host $host:$server_port;
  7. }
  8. include /etc/nginx/static.conf;
  9. }

2.5 利用switchHost工具添加域名映射:

image.png

2.6 在zyg-manager-web工程下的goodsController中添加如下方法:

  1. /**
  2. * 功能: 根据商品id生成商品静态面
  3. * 参数:
  4. * 返回值:
  5. * 时间: 2021/8/6 14:31
  6. */
  7. @RequestMapping("/item")
  8. public void createHtml(Long goodsId) throws IOException {
  9. pageSerivce.createHtml(goodsId);
  10. }

2.7 在zyg-page-service工程添加createHtml方法:

  1. /**
  2. * ------------------------------
  3. * 功能:
  4. * 作者:WF
  5. * 微信:hbxfwf13590332912
  6. * 创建时间:2021/8/6-14:37
  7. * ------------------------------
  8. */
  9. @Service
  10. public class PageServiceImpl implements PageSerivce {
  11. //1. 引入模板引擎
  12. @Autowired
  13. private TemplateEngine engine;
  14. //2. 引入其它mapper
  15. @Autowired
  16. private GoodsDao goodsDao;
  17. @Autowired
  18. private GoodsDescDao goodsDescDao;
  19. @Autowired
  20. private ItemDao itemDao;
  21. /**
  22. * 功能: 根据spu商品id生成静态页面
  23. * 参数:
  24. * 返回值: void
  25. * 时间: 2021/8/6 14:37
  26. */
  27. @Override
  28. public void createHtml(Long goodsId) throws IOException {
  29. //1. 定义模板工作的上下文环境对象
  30. Context context = new Context();
  31. //2. 定义存放商品数据的集合
  32. Map<String, Object> goodsMap = new HashMap<>();
  33. //4. 向集合中添加内容
  34. //4.1 查询spu商品信息
  35. GoodsEntity goodsEntity = goodsDao.selectById(goodsId);
  36. //4.2 查询商品描述信息
  37. GoodsDescEntity goodsDescEntity = goodsDescDao.selectById(goodsId);
  38. //4.3 查询sku商品列表
  39. QueryWrapper<ItemEntity> itemQueryWrapper = new QueryWrapper<ItemEntity>().eq("goods_id", goodsId)
  40. .orderByDesc("is_default");
  41. List<ItemEntity> items = itemDao.selectList(itemQueryWrapper);
  42. //4.4 处理ItemEntity中的spec字符串为Map对象
  43. for (ItemEntity item : items) {
  44. String spec = item.getSpec();
  45. Map map = JSON.parseObject(spec, Map.class);
  46. item.setSpecMap(map);
  47. }
  48. //4.5 重新组织数据
  49. List<Map> itemImages = JSON.parseArray(goodsDescEntity.getItemImages(), Map.class);
  50. List<Map> customAttributeItems = JSON.parseArray(goodsDescEntity.getCustomAttributeItems(), Map.class);
  51. List<Map> specificationItems = JSON.parseArray(goodsDescEntity.getSpecificationItems(), Map.class);
  52. //将商品信息放到map中
  53. goodsMap.put("goods",goodsEntity);
  54. goodsMap.put("itemImages",itemImages);
  55. goodsMap.put("customAttributeItems",customAttributeItems);
  56. goodsMap.put("specificationItems",specificationItems);
  57. goodsMap.put("goodsDesc",goodsDescEntity);
  58. goodsMap.put("items",items);
  59. //3. 绑定集合
  60. context.setVariables(goodsMap);
  61. //定义要输出的文件流
  62. File file = new File("D:\\nginx-1.8.0\\html\\item\\" + goodsId + ".html");
  63. Writer writer = new FileWriter(file);
  64. //执行相关操作
  65. engine.process("item",context,writer);
  66. }
  67. }

2.8 在zyg-page-service工程resources/template/item.html中内容:

  1. <!DOCTYPE html>
  2. <html xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE">
  6. <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
  7. <title>产品详情页</title>
  8. <link rel="icon" href="assets/img/favicon.ico">
  9. <link rel="stylesheet" type="text/css" href="css/webbase.css" />
  10. <link rel="stylesheet" type="text/css" href="css/pages-item.css" />
  11. <link rel="stylesheet" type="text/css" href="css/pages-zoom.css" />
  12. <link rel="stylesheet" type="text/css" href="css/widget-cartPanelView.css" />
  13. <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  14. </head>
  15. <script th:inline="javascript">
  16. //1. 得到sku商品列表
  17. let skuList = [[${items}]];
  18. //2. 开始得到默认sku商品的specMap值
  19. let items = JSON.parse(JSON.stringify(skuList[0].specMap));
  20. //3. 得到商品规格信息
  21. function addMyClass(attrName,attrValue,specIndex,optionIndex){
  22. let flag = false;
  23. //3.1 遍历skuList判断是否其中的attrName与attrValue与传入的值相等
  24. skuList.forEach(sku=>{
  25. if(sku.specMap[attrName] == attrValue){
  26. flag = true;
  27. }
  28. })
  29. //3.2 清空原来的规格格式
  30. $("#spec" + specIndex + " a").removeClass("selected");
  31. //3.3 设置选中项的样式
  32. if(flag){
  33. $("#spec"+specIndex + optionIndex).addClass("selected");
  34. }
  35. //3.4 点击了规格选项后,动态修改各个商品参数的值
  36. //3.4.1 动态为当前选择的对象赋值
  37. items[attrName] = attrValue;
  38. //3.4.2 根据当前用户点击得到的规格名称及规格选项参数得到规格对象
  39. let sku = selectSpec(items);
  40. //3.4.3 为商品标题设置值
  41. $("#title").html(sku.title);
  42. $("#price").html(sku.price);
  43. }
  44. //比较两个对象是否相等
  45. function matchObject(map1,map2){
  46. for(let i in map1){
  47. if(map1[i] != map2[i]){
  48. return false;
  49. }
  50. }
  51. for(let i in map2){
  52. if(map2[i] != map1[i]){
  53. return false;
  54. }
  55. }
  56. return true;
  57. }
  58. //判断点击规格时哪个规格是否与skuList中的某个spec是否相等
  59. function selectSpec(specificationItems){
  60. for(let i = 0;i < skuList.length;i++){
  61. if(matchObject(specificationItems,skuList[i].specMap)){
  62. return skuList[i];
  63. }
  64. }
  65. }
  66. </script>
  67. <body>
  68. <!--页面顶部 开始-->
  69. <div id="nav-bottom">
  70. <!--顶部-->
  71. <div class="nav-top">
  72. <div class="top">
  73. <div class="py-container">
  74. <div class="shortcut">
  75. <ul class="fl">
  76. <li class="f-item">泽易购欢迎您!</li>
  77. <li class="f-item"><a href="login.html" target="_blank">登录</a> <span><a href="register.html" target="_blank">免费注册</a></span></li>
  78. </ul>
  79. <ul class="fr">
  80. <li class="f-item">我的订单</li>
  81. <li class="f-item space"></li>
  82. <li class="f-item"><a href="home.html" target="_blank">我的泽易购</a></li>
  83. <li class="f-item space"></li>
  84. <li class="f-item">泽易购会员</li>
  85. <li class="f-item space"></li>
  86. <li class="f-item">企业采购</li>
  87. <li class="f-item space"></li>
  88. <li class="f-item">关注泽易购</li>
  89. <li class="f-item space"></li>
  90. <li class="f-item" id="service">
  91. <span>客户服务</span>
  92. <ul class="service">
  93. <li><a href="cooperation.html" target="_blank">合作招商</a></li>
  94. <li><a href="shoplogin.html" target="_blank">商家后台</a></li>
  95. <li><a href="cooperation.html" target="_blank">合作招商</a></li>
  96. <li><a href="#">商家后台</a></li>
  97. </ul>
  98. </li>
  99. <li class="f-item space"></li>
  100. <li class="f-item">网站导航</li>
  101. </ul>
  102. </div>
  103. </div>
  104. </div>
  105. <!--头部-->
  106. <div class="header">
  107. <div class="py-container">
  108. <div class="yui3-g Logo">
  109. <div class="yui3-u Left logoArea">
  110. <a class="logo-bd" title="泽易购" href="JD-index.html" target="_blank"></a>
  111. </div>
  112. <div class="yui3-u Center searchArea">
  113. <div class="search">
  114. <form action="" class="sui-form form-inline">
  115. <!--searchAutoComplete-->
  116. <div class="input-append">
  117. <input type="text" id="autocomplete" class="input-error input-xxlarge" />
  118. <button class="sui-btn btn-xlarge btn-danger" type="button">搜索</button>
  119. </div>
  120. </form>
  121. </div>
  122. <div class="hotwords">
  123. <ul>
  124. <li class="f-item">泽易购首发</li>
  125. <li class="f-item">亿元优惠</li>
  126. <li class="f-item">9.9元团购</li>
  127. <li class="f-item">每满99减30</li>
  128. <li class="f-item">亿元优惠</li>
  129. <li class="f-item">9.9元团购</li>
  130. <li class="f-item">办公用品</li>
  131. </ul>
  132. </div>
  133. </div>
  134. <div class="yui3-u Right shopArea">
  135. <div class="fr shopcar">
  136. <div class="show-shopcar" id="shopcar">
  137. <span class="car"></span>
  138. <a class="sui-btn btn-default btn-xlarge" href="cart.html" target="_blank">
  139. <span>我的购物车</span>
  140. <i class="shopnum">0</i>
  141. </a>
  142. <div class="clearfix shopcarlist" id="shopcarlist" style="display:none">
  143. <p>"啊哦,你的购物车还没有商品哦!"</p>
  144. <p>"啊哦,你的购物车还没有商品哦!"</p>
  145. </div>
  146. </div>
  147. </div>
  148. </div>
  149. </div>
  150. <div class="yui3-g NavList">
  151. <div class="yui3-u Left all-sort">
  152. <h4>全部商品分类</h4>
  153. </div>
  154. <div class="yui3-u Center navArea">
  155. <ul class="nav">
  156. <li class="f-item">服装城</li>
  157. <li class="f-item">美妆馆</li>
  158. <li class="f-item">品优超市</li>
  159. <li class="f-item">全球购</li>
  160. <li class="f-item">闪购</li>
  161. <li class="f-item">团购</li>
  162. <li class="f-item">有趣</li>
  163. <li class="f-item"><a href="seckill-index.html" target="_blank">秒杀</a></li>
  164. </ul>
  165. </div>
  166. <div class="yui3-u Right"></div>
  167. </div>
  168. </div>
  169. </div>
  170. </div>
  171. </div>
  172. <!--页面顶部 结束-->
  173. <div class="py-container">
  174. <div id="item">
  175. <div class="crumb-wrap">
  176. <ul class="sui-breadcrumb">
  177. <li>
  178. <a href="#">手机、数码、通讯</a>
  179. </li>
  180. <li>
  181. <a href="#">手机</a>
  182. </li>
  183. <li>
  184. <a href="#">Apple苹果</a>
  185. </li>
  186. <li class="active">iphone 6S系类</li>
  187. </ul>
  188. </div>
  189. <!--product-info-->
  190. <div class="product-info">
  191. <div class="fl preview-wrap">
  192. <!--放大镜效果-->
  193. <div class="zoom">
  194. <!--默认第一个预览-->
  195. <div id="preview" class="spec-preview">
  196. <span class="jqzoom">
  197. <img th:jqimg="${itemImages[0].url}" th:src="${itemImages[0].url}" /></span>
  198. </div>
  199. <!--下方的缩略图-->
  200. <div class="spec-scroll">
  201. <a class="prev">&lt;</a>
  202. <!--左右按钮-->
  203. <div class="items">
  204. <ul>
  205. <li th:each="img : ${itemImages}">
  206. <img th:src="${img.url}" th:bimg="${img.url}" onmousemove="preview(this)" />
  207. </li>
  208. </ul>
  209. </div>
  210. <a class="next">&gt;</a>
  211. </div>
  212. </div>
  213. </div>
  214. <div class="fr itemInfo-wrap">
  215. <div class="sku-name">
  216. <h4 id="title">[[${items[0].title}]]</h4>
  217. </div>
  218. <div class="news"><span th:utext="${goods.caption}" id="caption">推荐选择下方[移动优惠购],手机套餐齐搞定,不用换号,每月还有花费返</span></div>
  219. <div class="summary">
  220. <div class="summary-wrap">
  221. <div class="fl title">
  222. <i>价  格</i>
  223. </div>
  224. <div class="fl price">
  225. <i>¥</i>
  226. <em id="price">[[${items[0].price}]]</em>
  227. <span>降价通知</span>
  228. </div>
  229. <div class="fr remark">
  230. <i>累计评价</i><em>612188</em>
  231. </div>
  232. </div>
  233. <div class="summary-wrap">
  234. <div class="fl title">
  235. <i>促  销</i>
  236. </div>
  237. <div class="fl fix-width">
  238. <i class="red-bg">加价购</i>
  239. <em class="t-gray">满999.00另加20.00元,或满1999.00另加30.00元,或满2999.00另加40.00元,即可在购物车换
  240. 购热销商品</em>
  241. </div>
  242. </div>
  243. </div>
  244. <div class="support">
  245. <div class="summary-wrap">
  246. <div class="fl title">
  247. <i>支  持</i>
  248. </div>
  249. <div class="fl fix-width">
  250. <em class="t-gray">以旧换新,闲置手机回收 4G套餐超值抢 礼品购</em>
  251. </div>
  252. </div>
  253. <div class="summary-wrap">
  254. <div class="fl title">
  255. <i>配 送 至</i>
  256. </div>
  257. <div class="fl fix-width">
  258. <em class="t-gray">满999.00另加20.00元,或满1999.00另加30.00元,或满2999.00另加40.00元,即可在购物车换购热销商品</em>
  259. </div>
  260. </div>
  261. </div>
  262. <div class="clearfix choose">
  263. <div id="specification" class="summary-wrap clearfix">
  264. <dl th:each="attr : ${customAttributeItems}">
  265. <dt>
  266. <div class="fl title">
  267. <i>[[${attr.text}]]</i>
  268. </div>
  269. </dt>
  270. <dd>
  271. <a href="javascript:;" >
  272. [[${attr.value}]]
  273. <span title="点击取消选择">&nbsp;</span>
  274. </a>
  275. </dd>
  276. </dl>
  277. <dl th:each="spec,specStat : ${specificationItems}" th:id="'spec' + ${specStat.index}">
  278. <dt>
  279. <div class="fl title">
  280. <i>[[${spec.attributeName}]]</i>
  281. </div>
  282. </dt>
  283. <dd th:each="val,stat : ${spec.attributeValue}" >
  284. <a th:onclick="addMyClass([[${spec.attributeName}]],[[${val}]],[[${specStat.index}]],[[${stat.index}]])"
  285. th:id="'spec' + ${specStat.index} + ${stat.index}"
  286. th:class="${#maps.containsKey(items[0].specMap, spec.attributeName)
  287. && #maps.containsValue(items[0].specMap, val) ? 'selected' : ''}">
  288. [[${val}]]
  289. <span title="点击取消选择">&nbsp;</span>
  290. </a>
  291. </dd>
  292. </dl>
  293. </div>
  294. <div class="summary-wrap">
  295. <div class="fl title">
  296. <div class="control-group">
  297. <div class="controls">
  298. <input autocomplete="off" type="text" value="1" minnum="1" class="itxt" />
  299. <a href="javascript:void(0)" class="increment plus">+</a>
  300. <a href="javascript:void(0)" class="increment mins">-</a>
  301. </div>
  302. </div>
  303. </div>
  304. <div class="fl">
  305. <ul class="btn-choose unstyled">
  306. <li>
  307. <a href="cart.html" target="_blank" class="sui-btn btn-danger addshopcar">加入购物车</a>
  308. </li>
  309. </ul>
  310. </div>
  311. </div>
  312. </div>
  313. </div>
  314. </div>
  315. <!--product-detail-->
  316. <div class="clearfix product-detail">
  317. <div class="fl aside">
  318. <ul class="sui-nav nav-tabs tab-wraped">
  319. <li class="active">
  320. <a href="#index" data-toggle="tab">
  321. <span>相关分类</span>
  322. </a>
  323. </li>
  324. <li>
  325. <a href="#profile" data-toggle="tab">
  326. <span>推荐品牌</span>
  327. </a>
  328. </li>
  329. </ul>
  330. <div class="tab-content tab-wraped">
  331. <div id="index" class="tab-pane active">
  332. <ul class="part-list unstyled">
  333. <li>手机</li>
  334. <li>手机壳</li>
  335. <li>内存卡</li>
  336. <li>Iphone配件</li>
  337. <li>贴膜</li>
  338. <li>手机耳机</li>
  339. <li>移动电源</li>
  340. <li>平板电脑</li>
  341. </ul>
  342. <ul class="goods-list unstyled">
  343. <li>
  344. <div class="list-wrap">
  345. <div class="p-img">
  346. <img src="img/_/part01.png" />
  347. </div>
  348. <div class="attr">
  349. <em>Apple苹果iPhone 6s (A1699)</em>
  350. </div>
  351. <div class="price">
  352. <strong>
  353. <em>¥</em>
  354. <i>6088.00</i>
  355. </strong>
  356. </div>
  357. <div class="operate">
  358. <a href="javascript:void(0);" class="sui-btn btn-bordered">加入购物车</a>
  359. </div>
  360. </div>
  361. </li>
  362. <li>
  363. <div class="list-wrap">
  364. <div class="p-img">
  365. <img src="img/_/part02.png" />
  366. </div>
  367. <div class="attr">
  368. <em>Apple苹果iPhone 6s (A1699)</em>
  369. </div>
  370. <div class="price">
  371. <strong>
  372. <em>¥</em>
  373. <i>6088.00</i>
  374. </strong>
  375. </div>
  376. <div class="operate">
  377. <a href="javascript:void(0);" class="sui-btn btn-bordered">加入购物车</a>
  378. </div>
  379. </div>
  380. </li>
  381. <li>
  382. <div class="list-wrap">
  383. <div class="p-img">
  384. <img src="img/_/part03.png" />
  385. </div>
  386. <div class="attr">
  387. <em>Apple苹果iPhone 6s (A1699)</em>
  388. </div>
  389. <div class="price">
  390. <strong>
  391. <em>¥</em>
  392. <i>6088.00</i>
  393. </strong>
  394. </div>
  395. <div class="operate">
  396. <a href="javascript:void(0);" class="sui-btn btn-bordered">加入购物车</a>
  397. </div>
  398. </div>
  399. <div class="list-wrap">
  400. <div class="p-img">
  401. <img src="img/_/part02.png" />
  402. </div>
  403. <div class="attr">
  404. <em>Apple苹果iPhone 6s (A1699)</em>
  405. </div>
  406. <div class="price">
  407. <strong>
  408. <em>¥</em>
  409. <i>6088.00</i>
  410. </strong>
  411. </div>
  412. <div class="operate">
  413. <a href="javascript:void(0);" class="sui-btn btn-bordered">加入购物车</a>
  414. </div>
  415. </div>
  416. <div class="list-wrap">
  417. <div class="p-img">
  418. <img src="img/_/part03.png" />
  419. </div>
  420. <div class="attr">
  421. <em>Apple苹果iPhone 6s (A1699)</em>
  422. </div>
  423. <div class="price">
  424. <strong>
  425. <em>¥</em>
  426. <i>6088.00</i>
  427. </strong>
  428. </div>
  429. <div class="operate">
  430. <a href="javascript:void(0);" class="sui-btn btn-bordered">加入购物车</a>
  431. </div>
  432. </div>
  433. </li>
  434. </ul>
  435. </div>
  436. <div id="profile" class="tab-pane">
  437. <p>推荐品牌</p>
  438. </div>
  439. </div>
  440. </div>
  441. <div class="fr detail">
  442. <div class="clearfix fitting">
  443. <h4 class="kt">选择搭配</h4>
  444. <div class="good-suits">
  445. <div class="fl master">
  446. <div class="list-wrap">
  447. <div class="p-img">
  448. <img src="img/_/l-m01.png" />
  449. </div>
  450. <em>¥5299</em>
  451. <i>+</i>
  452. </div>
  453. </div>
  454. <div class="fl suits">
  455. <ul class="suit-list">
  456. <li class="">
  457. <div id="">
  458. <img src="img/_/dp01.png" />
  459. </div>
  460. <i>Feless费勒斯VR</i>
  461. <label data-toggle="checkbox" class="checkbox-pretty">
  462. <input type="checkbox"><span>39</span>
  463. </label>
  464. </li>
  465. <li class="">
  466. <div id=""><img src="img/_/dp02.png" /> </div>
  467. <i>Feless费勒斯VR</i>
  468. <label data-toggle="checkbox" class="checkbox-pretty">
  469. <input type="checkbox"><span>50</span>
  470. </label>
  471. </li>
  472. <li class="">
  473. <div id=""><img src="img/_/dp03.png" /></div>
  474. <i>Feless费勒斯VR</i>
  475. <label data-toggle="checkbox" class="checkbox-pretty">
  476. <input type="checkbox"><span>59</span>
  477. </label>
  478. </li>
  479. <li class="">
  480. <div id=""><img src="img/_/dp04.png" /></div>
  481. <i>Feless费勒斯VR</i>
  482. <label data-toggle="checkbox" class="checkbox-pretty">
  483. <input type="checkbox"><span>99</span>
  484. </label>
  485. </li>
  486. </ul>
  487. </div>
  488. <div class="fr result">
  489. <div class="num">已选购0件商品</div>
  490. <div class="price-tit"><strong>套餐价</strong></div>
  491. <div class="price">¥5299</div>
  492. <button class="sui-btn btn-danger addshopcar">加入购物车</button>
  493. </div>
  494. </div>
  495. </div>
  496. <div class="tab-main intro">
  497. <ul class="sui-nav nav-tabs tab-wraped">
  498. <li class="active">
  499. <a href="#one" data-toggle="tab">
  500. <span>商品介绍</span>
  501. </a>
  502. </li>
  503. <li>
  504. <a href="#two" data-toggle="tab">
  505. <span>规格与包装</span>
  506. </a>
  507. </li>
  508. <li>
  509. <a href="#three" data-toggle="tab">
  510. <span>售后保障</span>
  511. </a>
  512. </li>
  513. <li>
  514. <a href="#four" data-toggle="tab">
  515. <span>商品评价</span>
  516. </a>
  517. </li>
  518. <li>
  519. <a href="#five" data-toggle="tab">
  520. <span>手机社区</span>
  521. </a>
  522. </li>
  523. </ul>
  524. <div class="clearfix"></div>
  525. <div class="tab-content tab-wraped">
  526. <div id="one" class="tab-pane active">
  527. <ul class="goods-intro unstyled" id="introduction">
  528. [[${goodsDesc.introduction}]]
  529. </ul>
  530. <div class="intro-detail">
  531. <img src="img/_/intro01.png" />
  532. <img src="img/_/intro02.png" />
  533. <img src="img/_/intro03.png" />
  534. </div>
  535. </div>
  536. <div id="two" class="tab-pane">
  537. <p id="packageList">[[${goodsDesc.packageList}]]</p>
  538. </div>
  539. <div id="three" class="tab-pane">
  540. <p id="saleService">[[${goodsDesc.saleService}]]</p>
  541. </div>
  542. <div id="four" class="tab-pane">
  543. <p>商品评价</p>
  544. </div>
  545. <div id="five" class="tab-pane">
  546. <p>手机社区</p>
  547. </div>
  548. </div>
  549. </div>
  550. </div>
  551. </div>
  552. <!--like-->
  553. <div class="clearfix"></div>
  554. <div class="like">
  555. <h4 class="kt">猜你喜欢</h4>
  556. <div class="like-list">
  557. <ul class="yui3-g">
  558. <li class="yui3-u-1-6">
  559. <div class="list-wrap">
  560. <div class="p-img">
  561. <img src="img/_/itemlike01.png" />
  562. </div>
  563. <div class="attr">
  564. <em>DELL戴尔Ins 15MR-7528SS 15英寸 银色 笔记本</em>
  565. </div>
  566. <div class="price">
  567. <strong>
  568. <em>¥</em>
  569. <i>3699.00</i>
  570. </strong>
  571. </div>
  572. <div class="commit">
  573. <i class="command">已有6人评价</i>
  574. </div>
  575. </div>
  576. </li>
  577. <li class="yui3-u-1-6">
  578. <div class="list-wrap">
  579. <div class="p-img">
  580. <img src="img/_/itemlike02.png" />
  581. </div>
  582. <div class="attr">
  583. <em>Apple苹果iPhone 6s/6s Plus 16G 64G 128G</em>
  584. </div>
  585. <div class="price">
  586. <strong>
  587. <em>¥</em>
  588. <i>4388.00</i>
  589. </strong>
  590. </div>
  591. <div class="commit">
  592. <i class="command">已有700人评价</i>
  593. </div>
  594. </div>
  595. </li>
  596. <li class="yui3-u-1-6">
  597. <div class="list-wrap">
  598. <div class="p-img">
  599. <img src="img/_/itemlike03.png" />
  600. </div>
  601. <div class="attr">
  602. <em>DELL戴尔Ins 15MR-7528SS 15英寸 银色 笔记本</em>
  603. </div>
  604. <div class="price">
  605. <strong>
  606. <em>¥</em>
  607. <i>4088.00</i>
  608. </strong>
  609. </div>
  610. <div class="commit">
  611. <i class="command">已有700人评价</i>
  612. </div>
  613. </div>
  614. </li>
  615. <li class="yui3-u-1-6">
  616. <div class="list-wrap">
  617. <div class="p-img">
  618. <img src="img/_/itemlike04.png" />
  619. </div>
  620. <div class="attr">
  621. <em>DELL戴尔Ins 15MR-7528SS 15英寸 银色 笔记本</em>
  622. </div>
  623. <div class="price">
  624. <strong>
  625. <em>¥</em>
  626. <i>4088.00</i>
  627. </strong>
  628. </div>
  629. <div class="commit">
  630. <i class="command">已有700人评价</i>
  631. </div>
  632. </div>
  633. </li>
  634. <li class="yui3-u-1-6">
  635. <div class="list-wrap">
  636. <div class="p-img">
  637. <img src="img/_/itemlike05.png" />
  638. </div>
  639. <div class="attr">
  640. <em>DELL戴尔Ins 15MR-7528SS 15英寸 银色 笔记本</em>
  641. </div>
  642. <div class="price">
  643. <strong>
  644. <em>¥</em>
  645. <i>4088.00</i>
  646. </strong>
  647. </div>
  648. <div class="commit">
  649. <i class="command">已有700人评价</i>
  650. </div>
  651. </div>
  652. </li>
  653. <li class="yui3-u-1-6">
  654. <div class="list-wrap">
  655. <div class="p-img">
  656. <img src="img/_/itemlike06.png" />
  657. </div>
  658. <div class="attr">
  659. <em>DELL戴尔Ins 15MR-7528SS 15英寸 银色 笔记本</em>
  660. </div>
  661. <div class="price">
  662. <strong>
  663. <em>¥</em>
  664. <i>4088.00</i>
  665. </strong>
  666. </div>
  667. <div class="commit">
  668. <i class="command">已有700人评价</i>
  669. </div>
  670. </div>
  671. </li>
  672. </ul>
  673. </div>
  674. </div>
  675. </div>
  676. </div>
  677. <!-- 底部栏位 -->
  678. <!--页面底部 开始 -->
  679. <div class="clearfix footer">
  680. <div class="py-container">
  681. <div class="footlink">
  682. <div class="Mod-service">
  683. <ul class="Mod-Service-list">
  684. <li class="grid-service-item intro intro1">
  685. <i class="serivce-item fl"></i>
  686. <div class="service-text">
  687. <h4>正品保障</h4>
  688. <p>正品保障,提供发票</p>
  689. </div>
  690. </li>
  691. <li class="grid-service-item intro intro2">
  692. <i class="serivce-item fl"></i>
  693. <div class="service-text">
  694. <h4>正品保障</h4>
  695. <p>正品保障,提供发票</p>
  696. </div>
  697. </li>
  698. <li class="grid-service-item intro intro3">
  699. <i class="serivce-item fl"></i>
  700. <div class="service-text">
  701. <h4>正品保障</h4>
  702. <p>正品保障,提供发票</p>
  703. </div>
  704. </li>
  705. <li class="grid-service-item intro intro4">
  706. <i class="serivce-item fl"></i>
  707. <div class="service-text">
  708. <h4>正品保障</h4>
  709. <p>正品保障,提供发票</p>
  710. </div>
  711. </li>
  712. <li class="grid-service-item intro intro5">
  713. <i class="serivce-item fl"></i>
  714. <div class="service-text">
  715. <h4>正品保障</h4>
  716. <p>正品保障,提供发票</p>
  717. </div>
  718. </li>
  719. </ul>
  720. </div>
  721. <div class="clearfix Mod-list">
  722. <div class="yui3-g">
  723. <div class="yui3-u-1-6">
  724. <h4>购物指南</h4>
  725. <ul class="unstyled">
  726. <li>购物流程</li>
  727. <li>会员介绍</li>
  728. <li>生活旅行/团购</li>
  729. <li>常见问题</li>
  730. <li>购物指南</li>
  731. </ul>
  732. </div>
  733. <div class="yui3-u-1-6">
  734. <h4>配送方式</h4>
  735. <ul class="unstyled">
  736. <li>上门自提</li>
  737. <li>211限时达</li>
  738. <li>配送服务查询</li>
  739. <li>配送费收取标准</li>
  740. <li>海外配送</li>
  741. </ul>
  742. </div>
  743. <div class="yui3-u-1-6">
  744. <h4>支付方式</h4>
  745. <ul class="unstyled">
  746. <li>货到付款</li>
  747. <li>在线支付</li>
  748. <li>分期付款</li>
  749. <li>邮局汇款</li>
  750. <li>公司转账</li>
  751. </ul>
  752. </div>
  753. <div class="yui3-u-1-6">
  754. <h4>售后服务</h4>
  755. <ul class="unstyled">
  756. <li>售后政策</li>
  757. <li>价格保护</li>
  758. <li>退款说明</li>
  759. <li>返修/退换货</li>
  760. <li>取消订单</li>
  761. </ul>
  762. </div>
  763. <div class="yui3-u-1-6">
  764. <h4>特色服务</h4>
  765. <ul class="unstyled">
  766. <li>夺宝岛</li>
  767. <li>DIY装机</li>
  768. <li>延保服务</li>
  769. <li>泽易购E卡</li>
  770. <li>泽易购通信</li>
  771. </ul>
  772. </div>
  773. <div class="yui3-u-1-6">
  774. <h4>帮助中心</h4>
  775. <img src="img/wx_cz.jpg">
  776. </div>
  777. </div>
  778. </div>
  779. <div class="Mod-copyright">
  780. <ul class="helpLink">
  781. <li>关于我们<span class="space"></span></li>
  782. <li>联系我们<span class="space"></span></li>
  783. <li>关于我们<span class="space"></span></li>
  784. <li>商家入驻<span class="space"></span></li>
  785. <li>营销中心<span class="space"></span></li>
  786. <li>友情链接<span class="space"></span></li>
  787. <li>关于我们<span class="space"></span></li>
  788. <li>营销中心<span class="space"></span></li>
  789. <li>友情链接<span class="space"></span></li>
  790. <li>关于我们</li>
  791. </ul>
  792. <p>地址:北京市昌平区建材城西路金燕龙办公楼一层 邮编:100096 电话:400-618-4000 传真:010-82935100</p>
  793. <p>京ICP备08001421号京公网安备110108007702</p>
  794. </div>
  795. </div>
  796. </div>
  797. </div>
  798. <!--侧栏面板开始-->
  799. <div class="J-global-toolbar">
  800. <div class="toolbar-wrap J-wrap">
  801. <div class="toolbar">
  802. <div class="toolbar-panels J-panel">
  803. <!-- 购物车 -->
  804. <div style="visibility: hidden;" class="J-content toolbar-panel tbar-panel-cart toolbar-animate-out">
  805. <h3 class="tbar-panel-header J-panel-header">
  806. <a href="" class="title"><i></i><em class="title">购物车</em></a>
  807. <span class="close-panel J-close" onclick="cartPanelView.tbar_panel_close('cart');" ></span>
  808. </h3>
  809. <div class="tbar-panel-main">
  810. <div class="tbar-panel-content J-panel-content">
  811. <div id="J-cart-tips" class="tbar-tipbox hide">
  812. <div class="tip-inner">
  813. <span class="tip-text">还没有登录,登录后商品将被保存</span>
  814. <a href="#none" class="tip-btn J-login">登录</a>
  815. </div>
  816. </div>
  817. <div id="J-cart-render">
  818. <!-- 列表 -->
  819. <div id="cart-list" class="tbar-cart-list">
  820. </div>
  821. </div>
  822. </div>
  823. </div>
  824. <!-- 小计 -->
  825. <div id="cart-footer" class="tbar-panel-footer J-panel-footer">
  826. <div class="tbar-checkout">
  827. <div class="jtc-number"> <strong class="J-count" id="cart-number">0</strong>件商品 </div>
  828. <div class="jtc-sum"> 共计:<strong class="J-total" id="cart-sum">¥0</strong> </div>
  829. <a class="jtc-btn J-btn" href="#none" target="_blank">去购物车结算</a>
  830. </div>
  831. </div>
  832. </div>
  833. <!-- 我的关注 -->
  834. <div style="visibility: hidden;" data-name="follow" class="J-content toolbar-panel tbar-panel-follow">
  835. <h3 class="tbar-panel-header J-panel-header">
  836. <a href="#" target="_blank" class="title"> <i></i> <em class="title">我的关注</em> </a>
  837. <span class="close-panel J-close" onclick="cartPanelView.tbar_panel_close('follow');"></span>
  838. </h3>
  839. <div class="tbar-panel-main">
  840. <div class="tbar-panel-content J-panel-content">
  841. <div class="tbar-tipbox2">
  842. <div class="tip-inner"> <i class="i-loading"></i> </div>
  843. </div>
  844. </div>
  845. </div>
  846. <div class="tbar-panel-footer J-panel-footer"></div>
  847. </div>
  848. <!-- 我的足迹 -->
  849. <div style="visibility: hidden;" class="J-content toolbar-panel tbar-panel-history toolbar-animate-in">
  850. <h3 class="tbar-panel-header J-panel-header">
  851. <a href="#" target="_blank" class="title"> <i></i> <em class="title">我的足迹</em> </a>
  852. <span class="close-panel J-close" onclick="cartPanelView.tbar_panel_close('history');"></span>
  853. </h3>
  854. <div class="tbar-panel-main">
  855. <div class="tbar-panel-content J-panel-content">
  856. <div class="jt-history-wrap">
  857. <ul>
  858. <!--<li class="jth-item">
  859. <a href="#" class="img-wrap"> <img src=".portal/img/like_03.png" height="100" width="100" /> </a>
  860. <a class="add-cart-button" href="#" target="_blank">加入购物车</a>
  861. <a href="#" target="_blank" class="price">¥498.00</a>
  862. </li>
  863. <li class="jth-item">
  864. <a href="#" class="img-wrap"> <img src="portal/img/like_02.png" height="100" width="100" /></a>
  865. <a class="add-cart-button" href="#" target="_blank">加入购物车</a>
  866. <a href="#" target="_blank" class="price">¥498.00</a>
  867. </li>-->
  868. </ul>
  869. <a href="#" class="history-bottom-more" target="_blank">查看更多足迹商品 &gt;&gt;</a>
  870. </div>
  871. </div>
  872. </div>
  873. <div class="tbar-panel-footer J-panel-footer"></div>
  874. </div>
  875. </div>
  876. <div class="toolbar-header"></div>
  877. <!-- 侧栏按钮 -->
  878. <div class="toolbar-tabs J-tab">
  879. <div onclick="cartPanelView.tabItemClick('cart')" class="toolbar-tab tbar-tab-cart" data="购物车" tag="cart" >
  880. <i class="tab-ico"></i>
  881. <em class="tab-text"></em>
  882. <span class="tab-sub J-count " id="tab-sub-cart-count">0</span>
  883. </div>
  884. <div onclick="cartPanelView.tabItemClick('follow')" class="toolbar-tab tbar-tab-follow" data="我的关注" tag="follow" >
  885. <i class="tab-ico"></i>
  886. <em class="tab-text"></em>
  887. <span class="tab-sub J-count hide">0</span>
  888. </div>
  889. <div onclick="cartPanelView.tabItemClick('history')" class="toolbar-tab tbar-tab-history" data="我的足迹" tag="history" >
  890. <i class="tab-ico"></i>
  891. <em class="tab-text"></em>
  892. <span class="tab-sub J-count hide">0</span>
  893. </div>
  894. </div>
  895. <div class="toolbar-footer">
  896. <div class="toolbar-tab tbar-tab-top" > <a href="#"> <i class="tab-ico "></i> <em class="footer-tab-text">顶部</em> </a> </div>
  897. <div class="toolbar-tab tbar-tab-feedback" > <a href="#" target="_blank"> <i class="tab-ico"></i> <em class="footer-tab-text ">反馈</em> </a> </div>
  898. </div>
  899. <div class="toolbar-mini"></div>
  900. </div>
  901. <div id="J-toolbar-load-hook"></div>
  902. </div>
  903. </div>
  904. <script type="text/template" id="tbar-cart-item-template">
  905. <div class="tbar-cart-item" >
  906. <div class="jtc-item-promo">
  907. <em class="promo-tag promo-mz">满赠<i class="arrow"></i></em>
  908. <div class="promo-text">已购满600元,您可领赠品</div>
  909. </div>
  910. <div class="jtc-item-goods">
  911. <span class="p-img"><a href="#" target="_blank"><img src="{2}" alt="{1}" height="50" width="50" /></a></span>
  912. <div class="p-name">
  913. <a href="#">{1}</a>
  914. </div>
  915. <div class="p-price"><strong>¥{3}</strong>×{4} </div>
  916. <a href="#none" class="p-del J-del">删除</a>
  917. </div>
  918. </div>
  919. </script>
  920. <script type="text/javascript" src="js/plugins/jquery/jquery.min.js"></script>
  921. <script type="text/javascript">
  922. $(function(){
  923. $("#service").hover(function(){
  924. $(".service").show();
  925. },function(){
  926. $(".service").hide();
  927. });
  928. $("#shopcar").hover(function(){
  929. $("#shopcarlist").show();
  930. },function(){
  931. $("#shopcarlist").hide();
  932. });
  933. })
  934. </script>
  935. <script type="text/javascript" src="js/model/cartModel.js"></script>
  936. <script type="text/javascript" src="js/plugins/jquery.easing/jquery.easing.min.js"></script>
  937. <script type="text/javascript" src="js/plugins/sui/sui.min.js"></script>
  938. <script type="text/javascript" src="js/plugins/jquery.jqzoom/jquery.jqzoom.js"></script>
  939. <script type="text/javascript" src="js/plugins/jquery.jqzoom/zoom.js"></script>
  940. <script type="text/javascript" src="index/index.js"></script>
  941. <!--页面底部 结束 -->
  942. </body>
  943. </html>

点击规格选项时,自动得到某个sku对象的实现思路:

image.png

2.9 最后效果如下:

image.png
image.png
image.png
image.png