Showing
6 changed files
with
346 additions
and
75 deletions
@@ -23,13 +23,15 @@ const CHANNEL = { | @@ -23,13 +23,15 @@ const CHANNEL = { | ||
23 | }; | 23 | }; |
24 | 24 | ||
25 | const _getChannel = (req, res) => { | 25 | const _getChannel = (req, res) => { |
26 | - const channel = req.cookies._Channel || ''; | 26 | + let channel = req.cookies._Channel; |
27 | 27 | ||
28 | if (!channel) { | 28 | if (!channel) { |
29 | res.cookie('_Channel', CHANNEL.boys, { | 29 | res.cookie('_Channel', CHANNEL.boys, { |
30 | domain: '.yohobuy.com', | 30 | domain: '.yohobuy.com', |
31 | maxAge: moment.duration(300, 'days').seconds() | 31 | maxAge: moment.duration(300, 'days').seconds() |
32 | }); | 32 | }); |
33 | + | ||
34 | + channel = 'boys'; // 设置默认值 | ||
33 | } | 35 | } |
34 | 36 | ||
35 | return channel; | 37 | return channel; |
@@ -47,30 +49,25 @@ const _getGender = (channel) => { | @@ -47,30 +49,25 @@ const _getGender = (channel) => { | ||
47 | }; | 49 | }; |
48 | 50 | ||
49 | /** | 51 | /** |
50 | - * 渲染商品详情 | 52 | + * 首屏渲染商品详情 |
51 | */ | 53 | */ |
52 | const showMain = (req, res, next) => { | 54 | const showMain = (req, res, next) => { |
53 | let pid = req.params[0]; | 55 | let pid = req.params[0]; |
54 | - let gid = req.params[1]; | ||
55 | let channel = _getChannel(req, res); | 56 | let channel = _getChannel(req, res); |
56 | let gender = _getGender(channel); | 57 | let gender = _getGender(channel); |
57 | 58 | ||
58 | - let saveCurrentGoodsInCookies = _.partial(service.saveRecentGoodInCookies, | ||
59 | - req.cookies._browse, | ||
60 | - req.cookies._browseskn, | ||
61 | - res | ||
62 | - ); | ||
63 | - | ||
64 | - return service.showMainAsync({ | ||
65 | - pid: pid, | ||
66 | - gid: gid, | ||
67 | - channel: channel, | ||
68 | - gender: gender, | 59 | + const nullUserInfo = { |
69 | uid: null, | 60 | uid: null, |
70 | isStudent: null, | 61 | isStudent: null, |
71 | vipLevel: null, | 62 | vipLevel: null, |
72 | - saveInCookies: saveCurrentGoodsInCookies | ||
73 | - }).then(result=> { | 63 | + saveInCookies: null |
64 | + }; | ||
65 | + | ||
66 | + return service.showMainAsync(Object.assign({ | ||
67 | + pid: pid, | ||
68 | + channel: channel, | ||
69 | + gender: gender | ||
70 | + }, nullUserInfo)).then(result=> { | ||
74 | return res.render('product/detail', Object.assign({ | 71 | return res.render('product/detail', Object.assign({ |
75 | module: 'product', | 72 | module: 'product', |
76 | page: 'detail', | 73 | page: 'detail', |
@@ -84,6 +81,47 @@ const showMain = (req, res, next) => { | @@ -84,6 +81,47 @@ const showMain = (req, res, next) => { | ||
84 | 81 | ||
85 | }; | 82 | }; |
86 | 83 | ||
84 | +const detailHeader = (req, res, next) => { | ||
85 | + let pid = req.query.productId || 0; | ||
86 | + let uid = req.user.uid || 0; | ||
87 | + let vipLevel = detailHelper.vipLevel(req.user.vip); | ||
88 | + let dataMd5 = req.query.md5 || 0; | ||
89 | + | ||
90 | + let saveCurrentGoodsInCookies = _.partial(service.saveRecentGoodInCookies, | ||
91 | + req.cookies._browseskn, | ||
92 | + res | ||
93 | + ); | ||
94 | + | ||
95 | + return service.getDetailHeader(pid, uid, req.user.isStudent, vipLevel, dataMd5, saveCurrentGoodsInCookies) | ||
96 | + .then((result) => { | ||
97 | + if (result.code === 200) { | ||
98 | + return res.render('product/detail-header', Object.assign({layout: false}, result.data)); | ||
99 | + } else { | ||
100 | + return res.status(204).end(); | ||
101 | + } | ||
102 | + }).catch(next); | ||
103 | +}; | ||
104 | + | ||
105 | +const detailReturn = (req, res, next) => { | ||
106 | + let skn = req.query.skn || 0; | ||
107 | + | ||
108 | + if (!skn) { | ||
109 | + return { | ||
110 | + code: 400, | ||
111 | + message: '商品数据出错' | ||
112 | + }; | ||
113 | + } | ||
114 | + | ||
115 | + return service.saleReturn(skn).then(result => { | ||
116 | + return res.json({ | ||
117 | + code: 200, | ||
118 | + data: { | ||
119 | + result: result | ||
120 | + } | ||
121 | + }); | ||
122 | + }).catch(next); | ||
123 | +}; | ||
124 | + | ||
87 | /** | 125 | /** |
88 | * 获取热区图 | 126 | * 获取热区图 |
89 | */ | 127 | */ |
@@ -182,22 +220,6 @@ const createConsult = (req, res, next) => { | @@ -182,22 +220,6 @@ const createConsult = (req, res, next) => { | ||
182 | } | 220 | } |
183 | }; | 221 | }; |
184 | 222 | ||
185 | -const detailHeader = (req, res, next) => { | ||
186 | - let pid = req.query.productId || 0; | ||
187 | - let uid = req.user.uid || 0; | ||
188 | - let vipLevel = detailHelper.vipLevel(req.user.vip); | ||
189 | - let dataMd5 = req.query.md5 || 0; | ||
190 | - | ||
191 | - // service.getDetailHeader(pid, uid, req.user.isStudent, vipLevel, dataMd5).then((result) => { | ||
192 | - // if (result.code === 200) { | ||
193 | - // return res.render('product/detail-header', Object.assign({layout: false}, result.data)); | ||
194 | - // } else { | ||
195 | - // return res.status(204).end(); | ||
196 | - // } | ||
197 | - // }).catch(next); | ||
198 | - | ||
199 | - return res.status(204).end(); | ||
200 | -}; | ||
201 | 223 | ||
202 | module.exports = { | 224 | module.exports = { |
203 | showMain, | 225 | showMain, |
@@ -205,8 +227,8 @@ module.exports = { | @@ -205,8 +227,8 @@ module.exports = { | ||
205 | indexComment, | 227 | indexComment, |
206 | indexConsult, | 228 | indexConsult, |
207 | createConsult, | 229 | createConsult, |
208 | - productHeader: detailHeader | ||
209 | - | 230 | + productHeader: detailHeader, |
231 | + detailReturn | ||
210 | }; | 232 | }; |
211 | 233 | ||
212 | 234 |
@@ -486,25 +486,16 @@ function _getSortNavAsync(smallSortId, gender) { | @@ -486,25 +486,16 @@ function _getSortNavAsync(smallSortId, gender) { | ||
486 | } | 486 | } |
487 | 487 | ||
488 | // 保存在 gids 和 skns ,最近流览功能 | 488 | // 保存在 gids 和 skns ,最近流览功能 |
489 | -const saveRecentGoodInCookies = (oldGids, oldSkns, res, addGids, addSkns) => { | ||
490 | - oldGids = (oldGids || '').split(','); | ||
491 | - oldSkns = (oldSkns || '').split(','); | ||
492 | - addSkns = `${addSkns}-${addGids}`; | 489 | +const saveRecentGoodInCookies = (oldSkns, res, addSkns) => { |
490 | + oldSkns = oldSkns || []; | ||
493 | 491 | ||
494 | - _.remove(oldGids, addGids); | ||
495 | _.remove(oldSkns, addSkns); | 492 | _.remove(oldSkns, addSkns); |
496 | 493 | ||
497 | - oldGids.unshift(addGids); | ||
498 | oldSkns.unshift(addSkns); | 494 | oldSkns.unshift(addSkns); |
499 | 495 | ||
500 | - res.cookie('_browse', oldGids.splice(0, 30).join(','), { | ||
501 | - maxAge: 2000000000, | ||
502 | - domain: 'yohobuy.com' | ||
503 | - }); | ||
504 | - | ||
505 | res.cookie('_browseskn', oldSkns.splice(0, 30).join(','), { | 496 | res.cookie('_browseskn', oldSkns.splice(0, 30).join(','), { |
506 | maxAge: 2000000000, | 497 | maxAge: 2000000000, |
507 | - domain: 'yohobuy.com' | 498 | + domain: '.yohobuy.com' |
508 | }); | 499 | }); |
509 | }; | 500 | }; |
510 | 501 | ||
@@ -1052,7 +1043,7 @@ const _getSeoByGoodsInfo = (goodsInfo, navs) => { | @@ -1052,7 +1043,7 @@ const _getSeoByGoodsInfo = (goodsInfo, navs) => { | ||
1052 | * @param origin Object 原始数据 | 1043 | * @param origin Object 原始数据 |
1053 | * @return result Object 格式化数据 | 1044 | * @return result Object 格式化数据 |
1054 | */ | 1045 | */ |
1055 | -const _detailDataPkg = (origin, uid, vipLevel) => { | 1046 | +const _detailDataPkg = (origin, uid, vipLevel, cookies) => { |
1056 | return co(function*() { | 1047 | return co(function*() { |
1057 | let result = {}; // 结果输出 | 1048 | let result = {}; // 结果输出 |
1058 | let md5 = origin.md5; | 1049 | let md5 = origin.md5; |
@@ -1286,19 +1277,25 @@ const _detailDataPkg = (origin, uid, vipLevel) => { | @@ -1286,19 +1277,25 @@ const _detailDataPkg = (origin, uid, vipLevel) => { | ||
1286 | } | 1277 | } |
1287 | } | 1278 | } |
1288 | 1279 | ||
1280 | + // 最近浏览功能 ,限量商品不加入到最近浏览 | ||
1281 | + if (!_.has(result, 'fashionTopGoods')) { | ||
1282 | + cookies && cookies(_.get(result, 'skn', '')); | ||
1283 | + } | ||
1284 | + | ||
1289 | return { | 1285 | return { |
1290 | goodsInfo: result, | 1286 | goodsInfo: result, |
1291 | banner: _.isEmpty(bandInfo) ? null : bandInfo, | 1287 | banner: _.isEmpty(bandInfo) ? null : bandInfo, |
1292 | - statGoodsInfo: statGoodsInfo | 1288 | + statGoodsInfo: statGoodsInfo, |
1289 | + latestWalk: 5 // 只显示5个 | ||
1293 | }; | 1290 | }; |
1294 | })(); | 1291 | })(); |
1295 | }; | 1292 | }; |
1296 | 1293 | ||
1297 | -const getDetailHeader = (pid, uid, isStudent, vipLevel, dataMd5) => { | ||
1298 | - let currentUserProductInfo = _.partial(_detailDataPkg, _, uid, vipLevel); | 1294 | +const getDetailHeader = (pid, uid, isStudent, vipLevel, dataMd5, cookie) => { |
1295 | + let currentUserProductInfo = _.partial(_detailDataPkg, _, uid, vipLevel, cookie); | ||
1299 | 1296 | ||
1300 | return productAPI.getProductAsync(pid, uid, isStudent, vipLevel) | 1297 | return productAPI.getProductAsync(pid, uid, isStudent, vipLevel) |
1301 | - .then(result => currentUserProductInfo(result)) | 1298 | + .then(currentUserProductInfo) |
1302 | .then((result) => { | 1299 | .then((result) => { |
1303 | if (result.goodsInfo.md5 !== dataMd5 || uid) { | 1300 | if (result.goodsInfo.md5 !== dataMd5 || uid) { |
1304 | return { | 1301 | return { |
@@ -1314,16 +1311,20 @@ const getDetailHeader = (pid, uid, isStudent, vipLevel, dataMd5) => { | @@ -1314,16 +1311,20 @@ const getDetailHeader = (pid, uid, isStudent, vipLevel, dataMd5) => { | ||
1314 | }); | 1311 | }); |
1315 | }; | 1312 | }; |
1316 | 1313 | ||
1314 | +const saleReturn = (skn) => { | ||
1315 | + return productAPI.isSupportReturnedSale(skn).then(result => _.get(result, `data.${skn}`, 'N') === 'N' ? 'Y' : 'N'); | ||
1316 | +}; | ||
1317 | + | ||
1317 | /** | 1318 | /** |
1318 | * 获取某一个商品详情主页面 | 1319 | * 获取某一个商品详情主页面 |
1319 | */ | 1320 | */ |
1320 | const showMainAsync = (data) => { | 1321 | const showMainAsync = (data) => { |
1321 | return co(function * () { | 1322 | return co(function * () { |
1322 | - let currentUserProductInfo = _.partial(_detailDataPkg, _, data.uid, data.vipLevel); | 1323 | + let curUserProduct = _.partial(_detailDataPkg, _, data.uid, data.vipLevel, data.gid, data.saveInCookies); |
1323 | 1324 | ||
1324 | // 获取并处理商品基本信息 | 1325 | // 获取并处理商品基本信息 |
1325 | let productInfo = yield productAPI.getProductAsync(data.pid, data.uid, data.isStudent, data.vipLevel) | 1326 | let productInfo = yield productAPI.getProductAsync(data.pid, data.uid, data.isStudent, data.vipLevel) |
1326 | - .then(currentUserProductInfo); | 1327 | + .then(curUserProduct); |
1327 | 1328 | ||
1328 | if (_.isEmpty(productInfo) || _.isEmpty(productInfo.goodsInfo)) { | 1329 | if (_.isEmpty(productInfo) || _.isEmpty(productInfo.goodsInfo)) { |
1329 | return Promise.reject({ | 1330 | return Promise.reject({ |
@@ -1334,7 +1335,7 @@ const showMainAsync = (data) => { | @@ -1334,7 +1335,7 @@ const showMainAsync = (data) => { | ||
1334 | let requestData = yield Promise.all([ | 1335 | let requestData = yield Promise.all([ |
1335 | _getSortNavAsync(productInfo.goodsInfo.smallSortId, data.gender), // 导航 | 1336 | _getSortNavAsync(productInfo.goodsInfo.smallSortId, data.gender), // 导航 |
1336 | HeaderModel.requestHeaderData(data.channel), // 头部数据 | 1337 | HeaderModel.requestHeaderData(data.channel), // 头部数据 |
1337 | - productAPI.isSupportReturnedSale(productInfo.goodsInfo.skn), // 退换货 | 1338 | + productAPI.isSupportReturnedSale(productInfo.goodsInfo.skn), // 退换货 TODO: |
1338 | _getProductIntroAsync(productInfo.goodsInfo.productId, productInfo.goodsInfo.skn) // 商品详细介绍 | 1339 | _getProductIntroAsync(productInfo.goodsInfo.productId, productInfo.goodsInfo.skn) // 商品详细介绍 |
1339 | ]); | 1340 | ]); |
1340 | 1341 | ||
@@ -1375,13 +1376,6 @@ const showMainAsync = (data) => { | @@ -1375,13 +1376,6 @@ const showMainAsync = (data) => { | ||
1375 | [{name: productInfo.goodsInfo.name}] | 1376 | [{name: productInfo.goodsInfo.name}] |
1376 | ); | 1377 | ); |
1377 | 1378 | ||
1378 | - // 最近浏览功能 ,限量商品不加入到最近浏览 | ||
1379 | - if (!_.has(productInfo, 'goodsInfo.fashionTopGoods')) { | ||
1380 | - data.saveInCookies(data.gid, _.get(productInfo, 'goodsInfo.skn', '')); | ||
1381 | - } | ||
1382 | - | ||
1383 | - // 只显示5个 | ||
1384 | - result.detail.latestWalk = 5; | ||
1385 | 1379 | ||
1386 | return result; | 1380 | return result; |
1387 | })(); | 1381 | })(); |
@@ -1395,5 +1389,6 @@ module.exports = { | @@ -1395,5 +1389,6 @@ module.exports = { | ||
1395 | showMainAsync: showMainAsync, // 获取某一个商品详情主页面 | 1389 | showMainAsync: showMainAsync, // 获取某一个商品详情主页面 |
1396 | indexHotAreaAsync: hotAreaService.indexAsync, // 获取某一个商品的热区数据 | 1390 | indexHotAreaAsync: hotAreaService.indexAsync, // 获取某一个商品的热区数据 |
1397 | saveRecentGoodInCookies, // 保存最近的商品 | 1391 | saveRecentGoodInCookies, // 保存最近的商品 |
1398 | - getDetailHeader | 1392 | + getDetailHeader, |
1393 | + saleReturn | ||
1399 | }; | 1394 | }; |
@@ -59,6 +59,8 @@ router.post('/detail/consult', auth, detail.createConsult);// 创建咨询 | @@ -59,6 +59,8 @@ router.post('/detail/consult', auth, detail.createConsult);// 创建咨询 | ||
59 | router.get('/detail/hotarea', detail.indexHotArea);// 商品热区 | 59 | router.get('/detail/hotarea', detail.indexHotArea);// 商品热区 |
60 | router.post('/index/favoriteBrand', favorite.changeFavoriteBrand);// 收藏品牌 | 60 | router.post('/index/favoriteBrand', favorite.changeFavoriteBrand);// 收藏品牌 |
61 | router.post('/item/togglecollect', favorite.collectProduct); // 收藏商品 | 61 | router.post('/item/togglecollect', favorite.collectProduct); // 收藏商品 |
62 | +router.get('/detail/header', detail.productHeader); // 价格数据重新获取接口 | ||
63 | +router.get('/detail/return', detail.detailReturn);// 特殊商品退换货 | ||
62 | 64 | ||
63 | // 搜索 | 65 | // 搜索 |
64 | router.get('/search/index', search.index); | 66 | router.get('/search/index', search.index); |
@@ -23,7 +23,8 @@ | @@ -23,7 +23,8 @@ | ||
23 | {{> common/path-nav}} | 23 | {{> common/path-nav}} |
24 | 24 | ||
25 | {{# goodsInfo}} | 25 | {{# goodsInfo}} |
26 | - <div class="main clearfix" data-skn="{{skn}}" data-id="{{productId}}"> | 26 | + <div class="main clearfix" data-skn="{{skn}}" data-id="{{productId}}" data-md5="{{md5}}" |
27 | + data-skn="{{skn}}"> | ||
27 | <div class="pull-left imgs clearfix"> | 28 | <div class="pull-left imgs clearfix"> |
28 | <div class="pull-left img"> | 29 | <div class="pull-left img"> |
29 | <div class="tags clearfix"> | 30 | <div class="tags clearfix"> |
@@ -540,12 +541,18 @@ | @@ -540,12 +541,18 @@ | ||
540 | <span class="title cur">商品详情 DETAILS</span> | 541 | <span class="title cur">商品详情 DETAILS</span> |
541 | </p> | 542 | </p> |
542 | <div id="details-html" class="details-html"> | 543 | <div id="details-html" class="details-html"> |
544 | + <div class="lazy-load-object"> | ||
545 | + <textarea class="datalazyload" style="visibility: hidden;"> | ||
546 | + <script>fetchHotArea();</script> | ||
547 | + </textarea> | ||
548 | + </div> | ||
543 | {{{details}}} | 549 | {{{details}}} |
544 | </div> | 550 | </div> |
545 | </div> | 551 | </div> |
546 | 552 | ||
547 | {{# consultComment}} | 553 | {{# consultComment}} |
548 | <div class="consult-comment info-block"> | 554 | <div class="consult-comment info-block"> |
555 | + | ||
549 | <p class="block-title"> | 556 | <p class="block-title"> |
550 | <span class="title">顾客咨询(<em class="consult-num">0</em>)</span> | 557 | <span class="title">顾客咨询(<em class="consult-num">0</em>)</span> |
551 | <span class="sep">|</span> | 558 | <span class="sep">|</span> |
@@ -599,6 +606,14 @@ | @@ -599,6 +606,14 @@ | ||
599 | </p> | 606 | </p> |
600 | </div> | 607 | </div> |
601 | </div> | 608 | </div> |
609 | + | ||
610 | + <div class="lazy-load-object"> | ||
611 | + <textarea class="datalazyload" style="visibility: hidden;"> | ||
612 | + <script>fetchComment(); | ||
613 | + fetchReturn();</script> | ||
614 | + </textarea> | ||
615 | + </div> | ||
616 | + | ||
602 | </div> | 617 | </div> |
603 | {{/ consultComment}} | 618 | {{/ consultComment}} |
604 | 619 | ||
@@ -635,11 +650,8 @@ | @@ -635,11 +650,8 @@ | ||
635 | </div> | 650 | </div> |
636 | </div> | 651 | </div> |
637 | 652 | ||
638 | - {{#if supportSaleReturnedService}} | ||
639 | <div class="support-saleReturned-service"></div> | 653 | <div class="support-saleReturned-service"></div> |
640 | - {{^}} | ||
641 | - <div class="not-support-saleReturned-service"></div> | ||
642 | - {{/if}} | 654 | + |
643 | 655 | ||
644 | <div class="service"></div> | 656 | <div class="service"></div> |
645 | {{#if latestWalk}} | 657 | {{#if latestWalk}} |
@@ -724,7 +736,8 @@ | @@ -724,7 +736,8 @@ | ||
724 | 736 | ||
725 | (function() { | 737 | (function() { |
726 | var mvl = document.createElement('script'); | 738 | var mvl = document.createElement('script'); |
727 | - mvl.type = 'text/javascript'; mvl.async = true; | 739 | + mvl.type = 'text/javascript'; |
740 | + mvl.async = true; | ||
728 | mvl.src = ('https:' == document.location.protocol ? 'https://static-ssl.mediav.com/mvl.js' : 'http://static.mediav.com/mvl.js'); | 741 | mvl.src = ('https:' == document.location.protocol ? 'https://static-ssl.mediav.com/mvl.js' : 'http://static.mediav.com/mvl.js'); |
729 | var s = document.getElementsByTagName('script')[0]; | 742 | var s = document.getElementsByTagName('script')[0]; |
730 | s.parentNode.insertBefore(mvl, s); | 743 | s.parentNode.insertBefore(mvl, s); |
public/js/plugins/lazy-load.js
0 → 100644
1 | +/* eslint-disable */ | ||
2 | +/** | ||
3 | + * Created by TaoHuang on 2016/10/10. | ||
4 | + */ | ||
5 | +function dataLazyLoad(doc) { | ||
6 | + | ||
7 | + // 兼容低版本 IE | ||
8 | + Function.prototype.bind = Function.prototype.bind || function(context) { | ||
9 | + var that = this; | ||
10 | + return function() { | ||
11 | + return that.apply(context, arguments); | ||
12 | + }; | ||
13 | + }; | ||
14 | + | ||
15 | + // 工具方法 begin | ||
16 | + var Util = { | ||
17 | + getElementsByClassName: function(cls) { | ||
18 | + if (doc.getElementsByClassName) { | ||
19 | + return doc.getElementsByClassName(cls); | ||
20 | + } | ||
21 | + | ||
22 | + var o = doc.getElementsByTagName("*"), | ||
23 | + rs = []; | ||
24 | + | ||
25 | + for (var i = 0, t, len = o.length; i < len; i++) { | ||
26 | + (t = o[i]) && ~t.className.indexOf(cls) && rs.push(t); | ||
27 | + } | ||
28 | + | ||
29 | + return rs; | ||
30 | + }, | ||
31 | + addEvent: function(ele, type, fn) { | ||
32 | + ele.attachEvent ? ele.attachEvent("on" + type, fn) : ele.addEventListener(type, fn, false); | ||
33 | + }, | ||
34 | + removeEvent: function(ele, type, fn) { | ||
35 | + ele.detachEvent ? ele.detachEvent("on" + type, fn) : ele.removeEventListener(type, fn, false); | ||
36 | + }, | ||
37 | + getPos: function(ele) { | ||
38 | + var pos = { | ||
39 | + x: 0, | ||
40 | + y: 0 | ||
41 | + }; | ||
42 | + | ||
43 | + while (ele.offsetParent) { | ||
44 | + pos.x += ele.offsetLeft; | ||
45 | + pos.y += ele.offsetTop; | ||
46 | + ele = ele.offsetParent; | ||
47 | + } | ||
48 | + | ||
49 | + return pos; | ||
50 | + }, | ||
51 | + getViewport: function() { | ||
52 | + var html = doc.documentElement; | ||
53 | + | ||
54 | + return { | ||
55 | + w: !window.innerWidth ? html.clientHeight : window.innerWidth, | ||
56 | + h: !window.innerHeight ? html.clientHeight : window.innerHeight | ||
57 | + }; | ||
58 | + }, | ||
59 | + getScrollHeight: function() { | ||
60 | + html = doc.documentElement, bd = doc.body; | ||
61 | + return Math.max(window.pageYOffset || 0, html.scrollTop, bd.scrollTop); | ||
62 | + }, | ||
63 | + getEleSize: function(ele) { | ||
64 | + return { | ||
65 | + w: ele.offsetWidth, | ||
66 | + h: ele.offsetHeight | ||
67 | + }; | ||
68 | + } | ||
69 | + }; | ||
70 | + // 工具方法 end | ||
71 | + | ||
72 | + return { | ||
73 | + threshold: 0, // {number} 阈值,预加载高度,单位(px) | ||
74 | + els: null, // {Array} 延迟加载元素集合(数组) | ||
75 | + fn: null, // {Function} scroll、resize、touchmove 所绑定方法,即为 pollTextareas() | ||
76 | + | ||
77 | + evalScripts: function(code) { | ||
78 | + var head = doc.getElementsByClassName("yoho-footer")[0], | ||
79 | + js = doc.createElement("script"); | ||
80 | + | ||
81 | + js.text = code; | ||
82 | + head.appendChild(js, head.firstChild); | ||
83 | + head.removeChild(js); | ||
84 | + }, | ||
85 | + | ||
86 | + evalStyles: function(code) { | ||
87 | + var head = doc.getElementsByTagName("head")[0], | ||
88 | + css = doc.createElement("style"); | ||
89 | + | ||
90 | + css.type = "text/css"; | ||
91 | + | ||
92 | + try { | ||
93 | + css.appendChild(doc.createTextNode(code)); | ||
94 | + } catch (e) { | ||
95 | + css.styleSheet.cssText = code; | ||
96 | + } | ||
97 | + | ||
98 | + head.appendChild(css); | ||
99 | + }, | ||
100 | + | ||
101 | + extractCode: function(str, isStyle) { | ||
102 | + var cata = isStyle ? "style" : "script", | ||
103 | + scriptFragment = "<" + cata + "[^>]*>([\\S\\s]*?)</" + cata + "\\s*>", | ||
104 | + matchAll = new RegExp(scriptFragment, "img"), | ||
105 | + matchOne = new RegExp(scriptFragment, "im"), | ||
106 | + matchResults = str.match(matchAll) || [], | ||
107 | + ret = []; | ||
108 | + | ||
109 | + for (var i = 0, len = matchResults.length; i < len; i++) { | ||
110 | + var temp = (matchResults[i].match(matchOne) || ["", ""])[1]; | ||
111 | + temp && ret.push(temp); | ||
112 | + } | ||
113 | + return ret; | ||
114 | + }, | ||
115 | + | ||
116 | + decodeHTML: function(str) { | ||
117 | + return str.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&") | ||
118 | + .replace(/</g, '<').replace(/>/g, '>'); | ||
119 | + }, | ||
120 | + | ||
121 | + insert: function(ele) { | ||
122 | + var parent = ele.parentNode, | ||
123 | + txt = this.decodeHTML(ele.innerHTML), | ||
124 | + matchStyles = this.extractCode(txt, true), | ||
125 | + matchScripts = this.extractCode(txt); | ||
126 | + | ||
127 | + parent.innerHTML = txt | ||
128 | + .replace(new RegExp("<script[^>]*>([\\S\\s]*?)</script\\s*>", "img"), "") | ||
129 | + .replace(new RegExp("<style[^>]*>([\\S\\s]*?)</style\\s*>", "img"), ""); | ||
130 | + | ||
131 | + if (matchStyles.length) { | ||
132 | + for (var i = matchStyles.length; i--;) { | ||
133 | + this.evalStyles(matchStyles[i]); | ||
134 | + } | ||
135 | + } | ||
136 | + | ||
137 | + | ||
138 | + // 如果延迟部分需要做 loading 效果 | ||
139 | + parent.className = parent.className.replace("loading", ""); | ||
140 | + | ||
141 | + if (matchScripts.length) { | ||
142 | + for (var i = 0, len = matchScripts.length; i < len; i++) { | ||
143 | + this.evalScripts(matchScripts[i]); | ||
144 | + } | ||
145 | + } | ||
146 | + }, | ||
147 | + | ||
148 | + inView: function(ele) { | ||
149 | + var top = Util.getPos(ele).y | ||
150 | + , viewVal = Util.getViewport().h | ||
151 | + , scrollVal = Util.getScrollHeight() | ||
152 | + , eleHeight = Util.getEleSize(ele).h; | ||
153 | + | ||
154 | + if (top >= scrollVal - eleHeight - this.threshold && top <= scrollVal + viewVal + this.threshold) { | ||
155 | + return true; | ||
156 | + } | ||
157 | + | ||
158 | + return false; | ||
159 | + }, | ||
160 | + | ||
161 | + pollTextareas: function() { | ||
162 | + // 需延迟加载的元素已经全部加载完 | ||
163 | + if (!this.els.length) { | ||
164 | + Util.removeEvent(window, "scroll", this.fn); | ||
165 | + Util.removeEvent(window, "resize", this.fn); | ||
166 | + Util.removeEvent(doc.body, "touchMove", this.fn); | ||
167 | + return; | ||
168 | + } | ||
169 | + | ||
170 | + // 判断是否需要加载 | ||
171 | + for (var i = this.els.length; i--;) { | ||
172 | + var ele = this.els[i]; | ||
173 | + | ||
174 | + if (!this.inView(ele)) { | ||
175 | + continue; | ||
176 | + } | ||
177 | + | ||
178 | + this.insert(ele); | ||
179 | + this.els.splice(i, 1); | ||
180 | + } | ||
181 | + }, | ||
182 | + | ||
183 | + init: function(config) { | ||
184 | + var cls = config.cls; | ||
185 | + this.threshold = config.threshold ? config.threshold : 0; | ||
186 | + | ||
187 | + this.els = Array.prototype.slice.call(Util.getElementsByClassName(cls)); | ||
188 | + this.fn = this.pollTextareas.bind(this); | ||
189 | + | ||
190 | + this.fn(); | ||
191 | + Util.addEvent(window, "scroll", this.fn); | ||
192 | + Util.addEvent(window, "resize", this.fn); | ||
193 | + Util.addEvent(doc.body, "touchMove", this.fn); | ||
194 | + } | ||
195 | + }; | ||
196 | +} | ||
197 | + | ||
198 | +module.exports = dataLazyLoad; | ||
199 | + | ||
200 | +/** | ||
201 | + * demo | ||
202 | + * datalazyload.init({ | ||
203 | + * cls: "datalazyload", // 需要延迟加载的类,即 textarea 的类名 | ||
204 | + * threshold: 100 // 距离底部多高,进行延迟加载的阈值 | ||
205 | + * }); | ||
206 | + */ |
@@ -11,13 +11,15 @@ | @@ -11,13 +11,15 @@ | ||
11 | 11 | ||
12 | var $ = require('yoho-jquery'), | 12 | var $ = require('yoho-jquery'), |
13 | lazyLoad = require('yoho-jquery-lazyload'), | 13 | lazyLoad = require('yoho-jquery-lazyload'), |
14 | + dataLazyLoad = require('../plugins/lazy-load')(document), | ||
14 | Handlebars = require('yoho-handlebars'); | 15 | Handlebars = require('yoho-handlebars'); |
15 | 16 | ||
16 | var bindEvent = $.Callbacks(); // eslint-disable-line | 17 | var bindEvent = $.Callbacks(); // eslint-disable-line |
17 | 18 | ||
18 | var $main = $('.main'), | 19 | var $main = $('.main'), |
19 | id = $main.data('id'), | 20 | id = $main.data('id'), |
20 | - md5 = $main.data('md5'); | 21 | + md5 = $main.data('md5'), |
22 | + skn = $main.data('skn'); | ||
21 | 23 | ||
22 | var SLIDETIME = 200; | 24 | var SLIDETIME = 200; |
23 | 25 | ||
@@ -27,6 +29,8 @@ var colTxt = { | @@ -27,6 +29,8 @@ var colTxt = { | ||
27 | hover: '取消收藏' | 29 | hover: '取消收藏' |
28 | }; | 30 | }; |
29 | 31 | ||
32 | +var $saleReturn = $('#saleReturn'); | ||
33 | + | ||
30 | bindEvent.add(function() { | 34 | bindEvent.add(function() { |
31 | var $imgShow = $('#img-show'), | 35 | var $imgShow = $('#img-show'), |
32 | $thumbs = $('#thumbs > .thumb-wrap'); | 36 | $thumbs = $('#thumbs > .thumb-wrap'); |
@@ -549,13 +553,15 @@ $('.after-service-switch').click(function() { | @@ -549,13 +553,15 @@ $('.after-service-switch').click(function() { | ||
549 | }); | 553 | }); |
550 | 554 | ||
551 | // 商品详情区的热点 | 555 | // 商品详情区的热点 |
552 | -$.ajax({ | 556 | + |
557 | +function fetchHotArea() { | ||
558 | + $.ajax({ | ||
553 | type: 'GET', | 559 | type: 'GET', |
554 | url: '/product/detail/hotarea', | 560 | url: '/product/detail/hotarea', |
555 | data: { | 561 | data: { |
556 | productId: id | 562 | productId: id |
557 | } | 563 | } |
558 | -}).then(function(html) { | 564 | + }).then(function(html) { |
559 | $('#details-html').prepend(html); | 565 | $('#details-html').prepend(html); |
560 | 566 | ||
561 | // 修正热区尺寸使居中 | 567 | // 修正热区尺寸使居中 |
@@ -569,13 +575,19 @@ $.ajax({ | @@ -569,13 +575,19 @@ $.ajax({ | ||
569 | }, function() { | 575 | }, function() { |
570 | $(this).removeClass('hover'); | 576 | $(this).removeClass('hover'); |
571 | }); | 577 | }); |
572 | -}); | 578 | + }); |
579 | +} | ||
573 | 580 | ||
574 | -// 商品详情懒加载 | 581 | +window.fetchHotArea = fetchHotArea; |
582 | + | ||
583 | +// 商品详情图片懒加载 | ||
575 | lazyLoad($('#details-html img')); | 584 | lazyLoad($('#details-html img')); |
576 | 585 | ||
586 | +// 数据懒加载 | ||
587 | +dataLazyLoad.init({cls: 'datalazyload', threshold: -50}); | ||
588 | + | ||
577 | // 咨询和评价 | 589 | // 咨询和评价 |
578 | -(function() { | 590 | +function fetchComment() { |
579 | var commentPage = 1, | 591 | var commentPage = 1, |
580 | consultPage = 1; | 592 | consultPage = 1; |
581 | 593 | ||
@@ -762,7 +774,28 @@ lazyLoad($('#details-html img')); | @@ -762,7 +774,28 @@ lazyLoad($('#details-html img')); | ||
762 | 774 | ||
763 | loadComments(); | 775 | loadComments(); |
764 | loadConsults(); | 776 | loadConsults(); |
765 | -}()); | 777 | +} |
778 | + | ||
779 | +window.fetchComment = fetchComment; | ||
780 | + | ||
781 | +// 特殊商品退换货 | ||
782 | +function fetchReturn() { | ||
783 | + return $.ajax({ | ||
784 | + type: 'GET', | ||
785 | + url: '/product/detail/return', | ||
786 | + data: { | ||
787 | + skn: skn | ||
788 | + } | ||
789 | + }).then(function(result) { | ||
790 | + if (result.code === 200) { | ||
791 | + if (result.data.result === 'N') { | ||
792 | + $saleReturn.removeClass().addClass('not-support-saleReturned-service'); | ||
793 | + } | ||
794 | + } | ||
795 | + }); | ||
796 | +} | ||
797 | + | ||
798 | +window.fetchReturn = fetchReturn; | ||
766 | 799 | ||
767 | // 首屏加载,绑定事件 | 800 | // 首屏加载,绑定事件 |
768 | bindEvent.fire(); | 801 | bindEvent.fire(); |
-
Please register or login to post a comment