Authored by yyq

header nav

  1 +'use strict';
  2 +
  3 +const headerModel = require('../../../doraemon/models/header');
  4 +
  5 +const headerNav = (req, res, next) => {
  6 + let channel = req.query.channel || req.yoho.channel;
  7 +
  8 + headerModel.getHeaderSubNav(channel).then(result => {
  9 + let resData = {code: 400};
  10 +
  11 + if (result && result.length) {
  12 + Object.assign(resData, {
  13 + code: 200,
  14 + data: result[0]
  15 + });
  16 + }
  17 +
  18 + res.send(resData);
  19 + }).catch(next);
  20 +};
  21 +
  22 +module.exports = {
  23 + headerNav
  24 +};
@@ -19,6 +19,8 @@ const getBanner = require(`${cRoot}/getBanner`); @@ -19,6 +19,8 @@ const getBanner = require(`${cRoot}/getBanner`);
19 const passport = require(`${cRoot}/passport`); 19 const passport = require(`${cRoot}/passport`);
20 const suggestFeedBack = require(`${cRoot}/suggestFeedBack`); 20 const suggestFeedBack = require(`${cRoot}/suggestFeedBack`);
21 21
  22 +const main = require(`${cRoot}/index`);
  23 +
22 router.get('/recentReview', rvCtrl.index); // 最近浏览 24 router.get('/recentReview', rvCtrl.index); // 最近浏览
23 router.post('/getRecommend', rvCtrl.getRecommend); // 为你优选 25 router.post('/getRecommend', rvCtrl.getRecommend); // 为你优选
24 26
@@ -32,6 +34,8 @@ router.get('/passport', passport.index); @@ -32,6 +34,8 @@ router.get('/passport', passport.index);
32 34
33 router.get('/suggestfeedback', suggestFeedBack.getFeedBack); 35 router.get('/suggestfeedback', suggestFeedBack.getFeedBack);
34 36
  37 +router.get('/header/nav', main.headerNav);
  38 +
35 module.exports = router; 39 module.exports = router;
36 40
37 41
@@ -16,6 +16,7 @@ const path = require('path'); @@ -16,6 +16,7 @@ const path = require('path');
16 const headerHtml = require('fs').readFileSync(path.resolve(__dirname, '../views/partial/headerNew.hbs')).toString(); 16 const headerHtml = require('fs').readFileSync(path.resolve(__dirname, '../views/partial/headerNew.hbs')).toString();
17 const template = Handlebars.compile(headerHtml); 17 const template = Handlebars.compile(headerHtml);
18 const logger = global.yoho.logger; 18 const logger = global.yoho.logger;
  19 +
19 /** 20 /**
20 * 获取菜单 21 * 获取菜单
21 * @param undefined 22 * @param undefined
@@ -225,6 +226,8 @@ const cacheHeaderHtml = { @@ -225,6 +226,8 @@ const cacheHeaderHtml = {
225 lifestyle: [] 226 lifestyle: []
226 }; 227 };
227 228
  229 +let cacheNavData;
  230 +
228 const THIRTY_MINUTES = 1000 * 60 * 10; 231 const THIRTY_MINUTES = 1000 * 60 * 10;
229 232
230 async function requestHeaderData(type) { 233 async function requestHeaderData(type) {
@@ -262,6 +265,8 @@ async function requestHeaderData(type) { @@ -262,6 +265,8 @@ async function requestHeaderData(type) {
262 265
263 if (res[0] && res[0].data) { 266 if (res[0] && res[0].data) {
264 Object.assign(resData.headerData, setHeaderData(res[0].data, type)); 267 Object.assign(resData.headerData, setHeaderData(res[0].data, type));
  268 +
  269 + cacheNavData = _.get(resData, 'headerData.subNavGroup', '');
265 } else { 270 } else {
266 logger.error('header api data empty'); 271 logger.error('header api data empty');
267 } 272 }
@@ -294,6 +299,20 @@ async function requestHeaderData(type) { @@ -294,6 +299,20 @@ async function requestHeaderData(type) {
294 return Promise.resolve({headerData: _html}); 299 return Promise.resolve({headerData: _html});
295 } 300 }
296 301
  302 +
  303 +async function getHeaderSubNav(type) {
  304 + if (_.isEmpty(cacheNavData)) {
  305 + let res = await getHeaderNavAsync();
  306 +
  307 + cacheNavData = _.get(setHeaderData(res.data, type), 'subNavGroup', []);
  308 + }
  309 +
  310 + return Promise.resolve(_.takeWhile(cacheNavData, o => {
  311 + return o.subType === type;
  312 + }));
  313 +}
  314 +
297 module.exports = { 315 module.exports = {
298 - requestHeaderData 316 + requestHeaderData,
  317 + getHeaderSubNav
299 }; 318 };
@@ -168,29 +168,6 @@ @@ -168,29 +168,6 @@
168 <span class="newlogo"></span> 168 <span class="newlogo"></span>
169 {{/if}} 169 {{/if}}
170 </a> 170 </a>
171 - {{#if thirdNav}}  
172 - <div class="third-nav-wrapper">  
173 - <div class="center-content">  
174 - <dl class="hide-list hide">  
175 - {{# thirdNav}}  
176 - <dt>  
177 - <h3 class=""><a href="{{link}}"{{#if @root.pageNoFollow}} rel="nofollow"{{/if}}>{{title}}</a></h3>  
178 - </dt>  
179 - {{#brandItems}}  
180 - <dd>  
181 - <a href="{{link}}"{{#if hot}}  
182 - class="hot"{{/if}}{{#if @root.pageNoFollow}} rel="nofollow"{{/if}}>{{brandName}}</a>  
183 - </dd>  
184 - {{/brandItems}}  
185 - {{/thirdNav}}  
186 - </dl>  
187 - <div class="show-detail" data-code="{{imgCode}}">  
188 - <a{{#if @root.pageNoFollow}} rel="nofollow"{{/if}}><img src="data:image/gif;base64,R0lGODlhAQABAJEAAAAAAP///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw=="></a>  
189 - <a class="title">热门小物优选</a>  
190 - </div>  
191 - </div>  
192 - </div>  
193 - {{/if}}  
194 </li> 171 </li>
195 {{/ subNav}} 172 {{/ subNav}}
196 </ul> 173 </ul>
  1 +{{# subNav}}
  2 + <li {{#if thirdNav}}class="contain-third"{{/if}}>
  3 + <a href="{{link}}"{{#if @root.pageNoFollow}} rel="nofollow"{{/if}}>{{name}}
  4 + {{#if isNew}}
  5 + <span class="newlogo"></span>
  6 + {{/if}}
  7 + </a>
  8 + {{#if thirdNav}}
  9 + <div class="third-nav-wrapper">
  10 + <div class="center-content">
  11 + <dl class="hide-list hide">
  12 + {{# thirdNav}}
  13 + <dt>
  14 + <h3 class=""><a href="{{link}}"{{#if @root.pageNoFollow}} rel="nofollow"{{/if}}>{{title}}</a></h3>
  15 + </dt>
  16 + {{#brandItems}}
  17 + <dd>
  18 + <a href="{{link}}"{{#if hot}}
  19 + class="hot"{{/if}}{{#if @root.pageNoFollow}} rel="nofollow"{{/if}}>{{brandName}}</a>
  20 + </dd>
  21 + {{/brandItems}}
  22 + {{/thirdNav}}
  23 + </dl>
  24 + <div class="show-detail" data-code="{{imgCode}}">
  25 + <a{{#if @root.pageNoFollow}} rel="nofollow"{{/if}}><img src="data:image/gif;base64,R0lGODlhAQABAJEAAAAAAP///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw=="></a>
  26 + <a class="title">热门小物优选</a>
  27 + </div>
  28 + </div>
  29 + </div>
  30 + {{/if}}
  31 + </li>
  32 +{{/ subNav}}
@@ -23,7 +23,7 @@ var $head = $('.head-wrapper'), @@ -23,7 +23,7 @@ var $head = $('.head-wrapper'),
23 $miniCart = $head.find('.mini-cart-wrapper'), 23 $miniCart = $head.find('.mini-cart-wrapper'),
24 $dropDown = $tool.find('.nav-drop-down-container'); 24 $dropDown = $tool.find('.nav-drop-down-container');
25 25
26 -var $subNav = $('.sub-nav-list.cure .contain-third'); 26 +var subNavFn;
27 27
28 var fetchUserInfoEvent = $.Callbacks('once'); // eslint-disable-line 28 var fetchUserInfoEvent = $.Callbacks('once'); // eslint-disable-line
29 29
@@ -100,6 +100,7 @@ $('.we-chat').mouseenter(function() { @@ -100,6 +100,7 @@ $('.we-chat').mouseenter(function() {
100 centerFn = handlebars.compile($('#simple-account-info-tpl').html() || ''); 100 centerFn = handlebars.compile($('#simple-account-info-tpl').html() || '');
101 loginFn = handlebars.compile($('#header-login-info-tpl').html() || ''); 101 loginFn = handlebars.compile($('#header-login-info-tpl').html() || '');
102 cartFn = require('hbs/header/mini-cart-tpl.hbs'); // handlebars.compile($('#mini-cart-tpl').html() || ''); 102 cartFn = require('hbs/header/mini-cart-tpl.hbs'); // handlebars.compile($('#mini-cart-tpl').html() || '');
  103 +subNavFn = require('mix/common/header-nav.hbs');
103 104
104 // handlebars helper 105 // handlebars helper
105 handlebars.registerHelper('notzero', function(v1, options) { 106 handlebars.registerHelper('notzero', function(v1, options) {
@@ -284,32 +285,6 @@ function getBannerAndNotice() { @@ -284,32 +285,6 @@ function getBannerAndNotice() {
284 }); 285 });
285 } 286 }
286 287
287 -// 格式化三级菜单  
288 -function formatThirdMenu() {  
289 - $subNav.each(function() {  
290 - var $thirdList = $(this).find('.hide-list'),  
291 - list = [],  
292 - i = 0;  
293 -  
294 - if ($thirdList.length) {  
295 - $thirdList.children().each(function() {  
296 - if (i % thirdLineNum === 0) {  
297 - list.push('');  
298 - }  
299 - list[list.length - 1] += this.outerHTML + '';  
300 - i++;  
301 - });  
302 - for (i = 0; i < 3; i++) {  
303 - if (!list[i]) {  
304 - return;  
305 - }  
306 - $thirdList.before('<dl class="category-list">' + list[i] + '</dl>');  
307 - }  
308 - $thirdList.remove();  
309 - }  
310 - });  
311 -}  
312 -  
313 // 更新头部登陆信息 288 // 更新头部登陆信息
314 function updateLoginInfo(data) { 289 function updateLoginInfo(data) {
315 if (data.curLevel * 1 === 3) { 290 if (data.curLevel * 1 === 3) {
@@ -590,8 +565,28 @@ function isSupportCss3Animation() { @@ -590,8 +565,28 @@ function isSupportCss3Animation() {
590 } 565 }
591 } 566 }
592 567
593 -// 处理pageCache频道显示异常问题  
594 -function syncPageChannel() { 568 +if (isSupportCss3Animation()) {
  569 + requestFrame = requestFrameAct();
  570 + window.setTimeout(tsAnimate, 3000);
  571 +} else {
  572 + window.setTimeout(fadeAnimate, 3000);
  573 +}
  574 +
  575 +// 菜单设置
  576 +(function() {
  577 + var headerNav = {
  578 + init() {
  579 + var that = this;
  580 +
  581 + this.syncPageChannel();
  582 +
  583 + this.$base = $('.sub-nav-list.cure');
  584 +
  585 + $('.contain-third', this.$base).mouseenter(function() {
  586 + that.getThirdNavs();
  587 + });
  588 + },
  589 + syncPageChannel() {
595 var $header = $('#yoho-header'), 590 var $header = $('#yoho-header'),
596 $navs; 591 $navs;
597 var channel = window.homePage || window.cookie('_Channel') || 'boys', 592 var channel = window.homePage || window.cookie('_Channel') || 'boys',
@@ -613,20 +608,96 @@ function syncPageChannel() { @@ -613,20 +608,96 @@ function syncPageChannel() {
613 608
614 // 更新频道颜色 609 // 更新频道颜色
615 $header.addClass(channel).find('.func-area').removeClass('hide'); 610 $header.addClass(channel).find('.func-area').removeClass('hide');
  611 + }
616 612
617 - // 更新三级菜单jq对象  
618 - $subNav = $('.sub-nav-list.cure .contain-third'); 613 + this.channel = channel;
  614 + },
  615 + getThirdNavs() {
  616 + var that = this;
  617 +
  618 + if (this.loaded || this.loading) {
  619 + return;
619 } 620 }
620 -}  
621 621
622 -if (isSupportCss3Animation()) {  
623 - requestFrame = requestFrameAct();  
624 - window.setTimeout(tsAnimate, 3000);  
625 -} else {  
626 - window.setTimeout(fadeAnimate, 3000);  
627 -}  
628 -syncPageChannel();  
629 -formatThirdMenu(); // 格式化三级菜单 622 + this.loading = true;
  623 +
  624 + $.ajax({
  625 + url: '/common/header/nav',
  626 + type: 'GET',
  627 + data: {channel: this.channel},
  628 + }).done(function(res) {
  629 + if (res.code === 200) {
  630 + that.loaded = true;
  631 + that.$base.html(subNavFn(res.data));
  632 + that.reseatThirdMenu();
  633 + }
  634 + }).always(function() {
  635 + that.loading = false;
  636 + });
  637 + },
  638 + reseatThirdMenu() {
  639 + $('.contain-third', this.$base).each(function() {
  640 + var $thirdList = $(this).find('.hide-list'),
  641 + list = [],
  642 + i = 0;
  643 +
  644 + if ($thirdList.length) {
  645 + $thirdList.children().each(function() {
  646 + if (i % thirdLineNum === 0) {
  647 + list.push('');
  648 + }
  649 + list[list.length - 1] += this.outerHTML + '';
  650 + i++;
  651 + });
  652 + for (i = 0; i < 3; i++) {
  653 + if (!list[i]) {
  654 + return;
  655 + }
  656 + $thirdList.before('<dl class="category-list">' + list[i] + '</dl>');
  657 + }
  658 + $thirdList.remove();
  659 + }
  660 + }).on({
  661 + mouseenter: function() {
  662 + var $thirdNav = $(this).children('.third-nav-wrapper'),
  663 + $show = $thirdNav.find('.show-detail'),
  664 + param = {};
  665 +
  666 + delayer = setTimeout(function() {
  667 + $thirdNav.show();
  668 + }, 200);
  669 +
  670 + if (!$show.length || $show.hasClass('show')) {
  671 + return;
  672 + }
  673 + param.content_code = $show.data().code;
  674 + param.client_type = 'web';
  675 + param.width = 337;
  676 + param.height = 250;
  677 + param._ = new Date();
  678 + $.getJSON('//new.yohobuy.com/common/getbanner?callback=?', param, function(JsonData) {
  679 + if (JsonData.code === 200) {
  680 + $show.addClass('show');
  681 + $show.find('img').attr('src', JsonData.data.src);
  682 + $show.find('a').attr('href', JsonData.data.url);
  683 + $show.find('.title').text(JsonData.data.title);
  684 + }
  685 + });
  686 + },
  687 + mouseleave: function() {
  688 + var $thirdNav = $(this).children('.third-nav-wrapper');
  689 +
  690 + if (delayer) {
  691 + clearTimeout(delayer);
  692 + }
  693 + $thirdNav.hide();
  694 + }
  695 + });
  696 + }
  697 + };
  698 +
  699 + headerNav.init();
  700 +}());
630 701
631 (function() { 702 (function() {
632 if (document.all && !document.querySelector) { 703 if (document.all && !document.querySelector) {
@@ -809,43 +880,6 @@ if ($miniCart && $miniCart.length) { @@ -809,43 +880,6 @@ if ($miniCart && $miniCart.length) {
809 }); 880 });
810 } 881 }
811 882
812 -$subNav.on({  
813 - mouseenter: function() {  
814 - var $thirdNav = $(this).children('.third-nav-wrapper'),  
815 - $show = $thirdNav.find('.show-detail'),  
816 - param = {};  
817 -  
818 - delayer = setTimeout(function() {  
819 - $thirdNav.show();  
820 - }, 200);  
821 -  
822 - if (!$show.length || $show.hasClass('show')) {  
823 - return;  
824 - }  
825 - param.content_code = $show.data().code;  
826 - param.client_type = 'web';  
827 - param.width = 337;  
828 - param.height = 250;  
829 - param._ = new Date();  
830 - $.getJSON('//new.yohobuy.com/common/getbanner?callback=?', param, function(JsonData) {  
831 - if (JsonData.code === 200) {  
832 - $show.addClass('show');  
833 - $show.find('img').attr('src', JsonData.data.src);  
834 - $show.find('a').attr('href', JsonData.data.url);  
835 - $show.find('.title').text(JsonData.data.title);  
836 - }  
837 - });  
838 - },  
839 - mouseleave: function() {  
840 - var $thirdNav = $(this).children('.third-nav-wrapper');  
841 -  
842 - if (delayer) {  
843 - clearTimeout(delayer);  
844 - }  
845 - $thirdNav.hide();  
846 - }  
847 -});  
848 -  
849 /** 883 /**
850 * 首次进入有弹窗 884 * 首次进入有弹窗
851 * @return {[type]} [description] 885 * @return {[type]} [description]