Authored by xuqi

guang detail

@@ -6,7 +6,97 @@ @@ -6,7 +6,97 @@
6 6
7 var $ = require('yoho.zepto'), 7 var $ = require('yoho.zepto'),
8 ellipsis = require('mlellipsis'), 8 ellipsis = require('mlellipsis'),
9 - lazyLoad = require('yoho.lazyload'); 9 + lazyLoad = require('yoho.lazyload'),
  10 + IScroll = require('iscroll/iscroll-probe');
  11 +
  12 +var $authorIntro = $('.author .intro');
  13 +
  14 +var isIphone = navigator.userAgent.indexOf('iPhone') > 0 ? true : false;
  15 +
  16 +var hasCollocationBlock = $('.collocation-block').length > 0 ? true : false;
  17 +
  18 +//collocation block variable
  19 +var thumbWidth = 0,
  20 + $fixedThumbContainer = $(''),
  21 + $coBlock, $thumbContainer, $thumbs, $prods,
  22 + scrollToEl;
  23 +
  24 +var scrollToEl = document.querySelector('#wrapper .collocation-block');
  25 +
  26 +var winW = $(window).width();
  27 +
  28 +var myScroll;
  29 +
  30 +/**
  31 + * 计算搭配的箭头的位置
  32 + * @param $curPos 当前focus的搭配项
  33 + */
  34 +function posCollocationArrow($curCo) {
  35 + var left = $curCo.offset().left,
  36 + bgPos = -winW + left + (thumbWidth / 2) + 'px';
  37 +
  38 + $thumbContainer.css({
  39 + backgroundPosition: bgPos + ' bottom'
  40 + });
  41 +
  42 + if (isIphone) {
  43 + $fixedThumbContainer.css({
  44 + backgroundPosition: bgPos + ' bottom'
  45 + });
  46 + }
  47 +}
  48 +
  49 +//搭配thumb的touch事件句柄
  50 +function thumbTouchEvt(e) {
  51 + var $curCo = $(e.currentTarget),
  52 + index = $curCo.index(),
  53 + $brother, $brotherCo,
  54 + $curProds;
  55 +
  56 + if ($curCo.hasClass('focus')) {
  57 + return;
  58 + }
  59 +
  60 + $thumbs.filter('.focus').removeClass('focus');
  61 +
  62 + if (isIphone) {
  63 + if ($curCo.closest('.fixed-thumb-container').length > 0) {
  64 + $brother = $thumbContainer;
  65 + } else {
  66 + $brother = $fixedThumbContainer;
  67 + }
  68 +
  69 + $brotherCo = $brother.find('.thumb').eq(index);
  70 + $fixedThumbContainer.find('.thumb.focus').removeClass('focus');
  71 + $brotherCo.addClass('focus');
  72 + }
  73 +
  74 + $curCo.addClass('focus');
  75 +
  76 + //定位arrow
  77 + posCollocationArrow($curCo);
  78 +
  79 + $prods.not('.hide').addClass('hide');
  80 + $curProds = $prods.eq(index);
  81 + $curProds.removeClass('hide');
  82 +
  83 + //
  84 + lazyLoad($curProds.find('.lazy'));
  85 +
  86 + if (isIphone) {
  87 + if (myScroll) {
  88 + myScroll.scrollToElement(scrollToEl, 400);
  89 + }
  90 + } else {
  91 + $('body').animate({
  92 + scrollTop: $coBlock.offset().top
  93 + }, 400);
  94 + }
  95 +}
  96 +
  97 +if (isIphone) {
  98 + $('#wrapper').addClass('ios');
  99 +}
10 100
11 ellipsis.init(); 101 ellipsis.init();
12 102
@@ -15,4 +105,114 @@ lazyLoad($('.lazy')); @@ -15,4 +105,114 @@ lazyLoad($('.lazy'));
15 //title mlellipsis 105 //title mlellipsis
16 $('.info-list .title, .one-good .reco-name').each(function() { 106 $('.info-list .title, .one-good .reco-name').each(function() {
17 this.mlellipsis(2); 107 this.mlellipsis(2);
18 -});  
  108 +});
  109 +
  110 +//offset.left约等于marginLeft的值则表示介绍被换行,则清除intro的paddingTop让其更靠近头像和作者名
  111 +if (parseInt($authorIntro.offset().left, 10) === parseInt($authorIntro.css('margin-left'), 10)) {
  112 + $authorIntro.css('padding-top', 0);
  113 +}
  114 +
  115 +//有搭配模块,iphone使用iscroll初始化滚动并有固定的搭配栏,其他的没有
  116 +if (hasCollocationBlock) {
  117 + $coBlock = $('.collocation-block');
  118 + $thumbContainer = $coBlock.children('.thumb-container');
  119 + $thumbs = $thumbContainer.find('li');
  120 + $prods = $coBlock.find('.prod');
  121 +
  122 + thumbWidth = $thumbs.width();
  123 +
  124 + if (isIphone) {
  125 + $fixedThumbContainer = $('#wrapper')
  126 + .after($thumbContainer.clone().addClass('fixed-thumb-container fixed-bottom'))
  127 + .next('.thumb-container');
  128 +
  129 + //load img of fixed thumb container
  130 + lazyLoad($fixedThumbContainer.find('.lazy'), {
  131 + event: 'sporty'
  132 + });
  133 + }
  134 +
  135 + //Init Arrow Position
  136 + posCollocationArrow($thumbs.filter('.focus'));
  137 +
  138 + $thumbContainer.delegate('.thumb', 'touchend', thumbTouchEvt);
  139 +
  140 + if (isIphone) {
  141 + $fixedThumbContainer.delegate('.thumb', 'touchend', thumbTouchEvt);
  142 + }
  143 +}
  144 +
  145 +// 初始化iscroll
  146 +window.onload = function() {
  147 + var $scroller = $('#scroller');
  148 +
  149 + var winH, tcH, cbH, cbTop, fixedThumbDom;
  150 +
  151 + if (!isIphone) {
  152 + return;
  153 + }
  154 +
  155 + myScroll = new IScroll('#wrapper', {
  156 + probeType: 3,
  157 + mouseWheel: true,
  158 + click: true
  159 + });
  160 +
  161 + document.addEventListener('touchmove', function (e) {
  162 + e.preventDefault();
  163 + }, false);
  164 +
  165 + if (!hasCollocationBlock) {
  166 + myScroll.on('scroll', function() {
  167 + $scroller.trigger('scroll');
  168 + });
  169 + return;
  170 + }
  171 +
  172 + winH = $(window).height();
  173 + fixedThumbDom = $fixedThumbContainer[0];
  174 +
  175 + tcH = $thumbContainer.height();
  176 + cbH = $coBlock.height();
  177 + cbTop = $coBlock.offset().top;
  178 +
  179 + myScroll.on('scroll', function() {
  180 + var sTop = -this.y;
  181 + var classList = fixedThumbDom.className;
  182 +
  183 + if (sTop <= cbTop - winH + tcH) {
  184 + if (classList.indexOf('fixed-bottom') === -1) {
  185 + $fixedThumbContainer
  186 + .addClass('fixed-bottom')
  187 + .removeClass('hide');
  188 + }
  189 + } else if (sTop <= cbTop) {
  190 + if (classList.indexOf('hide') === -1) {
  191 + $fixedThumbContainer
  192 + .addClass('hide')
  193 + .removeClass('fixed-bottom fixed-top');
  194 + }
  195 + } else if (sTop <= cbTop + cbH - tcH) {
  196 + if (classList.indexOf('fixed-top') === -1) {
  197 + $fixedThumbContainer
  198 + .addClass('fixed-top')
  199 + .removeClass('hide absolute')
  200 + .css('top', '');
  201 + }
  202 + } else if (sTop <= cbTop + cbH) {
  203 + if (classList.indexOf('absolute') === -1) {
  204 + $fixedThumbContainer
  205 + .addClass('absolute')
  206 + .removeClass('fixed-top hide');
  207 + }
  208 + fixedThumbDom.style.top = cbTop + cbH - tcH - sTop + 'px';
  209 + } else if (sTop > cbTop + cbH) {
  210 + if (classList.indexOf('hide') === -1) {
  211 + $fixedThumbContainer
  212 + .addClass('hide')
  213 + .removeClass('absolute');
  214 + }
  215 + }
  216 + $scroller.trigger('scroll');
  217 + });
  218 +};
@@ -20,7 +20,8 @@ @@ -20,7 +20,8 @@
20 "yoho.jquery": "1.8.3", 20 "yoho.jquery": "1.8.3",
21 "yoho.lazyload": "1.1.0", 21 "yoho.lazyload": "1.1.0",
22 "mlellipsis": "0.0.6", 22 "mlellipsis": "0.0.6",
23 - "yoho.iswiper": "3.0.1" 23 + "yoho.iswiper": "3.0.1",
  24 + "iscroll": "5.1.2"
24 }, 25 },
25 "devDependencies": { 26 "devDependencies": {
26 "expect.js": "0.3.1" 27 "expect.js": "0.3.1"
@@ -55,16 +55,16 @@ $clothes: sprite-map("guang/clothes/*.png"); @@ -55,16 +55,16 @@ $clothes: sprite-map("guang/clothes/*.png");
55 float: left; 55 float: left;
56 font-size: 28rem / $pxConvertRem; 56 font-size: 28rem / $pxConvertRem;
57 color: #000; 57 color: #000;
58 - padding: 30rem / $pxConvertRem;  
59 - margin-left: 30rem / $pxConvertRem 0; 58 + padding: 30rem / $pxConvertRem 0;
  59 + margin-left: 30rem / $pxConvertRem;
60 } 60 }
61 61
62 .intro { 62 .intro {
63 float: left; 63 float: left;
64 font-size: 28rem / $pxConvertRem; 64 font-size: 28rem / $pxConvertRem;
65 color: #b0b0b0; 65 color: #b0b0b0;
66 - padding: 30rem / $pxConvertRem;  
67 - margin-left: 30rem / $pxConvertRem 0; 66 + padding: 30rem / $pxConvertRem 0;
  67 + margin-left: 30rem / $pxConvertRem;
68 } 68 }
69 } 69 }
70 70
@@ -116,131 +116,135 @@ $clothes: sprite-map("guang/clothes/*.png"); @@ -116,131 +116,135 @@ $clothes: sprite-map("guang/clothes/*.png");
116 .collocation-block { 116 .collocation-block {
117 background: #fff; 117 background: #fff;
118 118
119 - .thumb-container {  
120 - padding-top: 30rem / $pxConvertRem;  
121 - padding-left: 30rem / $pxConvertRem;  
122 - background: transparent image-url('guang/thumb-container-bg.png') no-repeat;  
123 - background-size: 100% 100%;  
124 -  
125 - &.fixed-top {  
126 - position: fixed;  
127 - left: 0;  
128 - right: 0;  
129 - top: 0;  
130 - }  
131 -  
132 - &.fixed-bottom {  
133 - position: fixed;  
134 - left: 0;  
135 - right: 0;  
136 - bottom: 0;  
137 - background: rgba(255,255,255,0.9);  
138 - }  
139 -  
140 - &.absolute {  
141 - position: absolute;  
142 - left: 0;  
143 - right: 0;  
144 - } 119 + .good-list {
  120 + padding-left:15rem / $pxConvertRem;
  121 + }
  122 + }
145 123
146 - &.static {  
147 - position: static;  
148 - } 124 + .thumb-container {
  125 + padding-top: 30rem / $pxConvertRem;
  126 + padding-left: 30rem / $pxConvertRem;
  127 + background: transparent image-url('guang/thumb-container-bg.png') no-repeat;
  128 + background-size: 200% 100%;
  129 +
  130 + &.fixed-top {
  131 + position: fixed;
  132 + left: 0;
  133 + right: 0;
  134 + top: 0;
149 } 135 }
150 136
151 - .thumb {  
152 - display: inline-block;  
153 - position: relative;  
154 - margin-right: 22rem / $pxConvertRem;  
155 - padding-bottom: 30rem / $pxConvertRem; 137 + &.fixed-bottom {
  138 + position: fixed;
  139 + left: 0;
  140 + right: 0;
  141 + bottom: 0;
  142 + background: rgba(255,255,255,0.9);
  143 + }
156 144
157 - &:last-child {  
158 - margin-right: 0;  
159 - } 145 + &.absolute {
  146 + position: absolute;
  147 + left: 0;
  148 + right: 0;
  149 + }
160 150
161 - &.focus .thumb-img {  
162 - border-color: #000;  
163 - } 151 + &.static {
  152 + position: static;
164 } 153 }
165 154
166 - .thumb-img {  
167 - height: 134rem / $pxConvertRem;  
168 - width: 96rem / $pxConvertRem;  
169 - border: 1px solid transparent; 155 + &.hide {
  156 + display: none;
170 } 157 }
  158 + }
171 159
172 - .good-list {  
173 - padding-left:15rem / $pxConvertRem; 160 + .clothe-type {
  161 + position: absolute;
  162 + right: 6rem / $pxConvertRem;
  163 + bottom: 34rem / $pxConvertRem;
  164 + width: 20px;
  165 + height: 20px;
  166 + @include border-radius(50%);
  167 +
  168 + &.bag {
  169 + @include retina-sprite ($clothes, bag, 80/20);
  170 + background-color: #fff;
  171 + background-size: 100%;
174 } 172 }
175 173
176 - .clothe-type {  
177 - position: absolute;  
178 - right: 6rem / $pxConvertRem;  
179 - bottom: 34rem / $pxConvertRem;  
180 - width: 20px;  
181 - height: 20px;  
182 - @include border-radius(50%);  
183 -  
184 - &.bag {  
185 - @include retina-sprite ($clothes, bag, 80/20);  
186 - background-color: #fff;  
187 - background-size: 100%;  
188 - }  
189 -  
190 - &.cloth {  
191 - @include retina-sprite ($clothes, cloth, 80/20);  
192 - background-color: #fff;  
193 - background-size: 100%;  
194 - }  
195 -  
196 - &.dress {  
197 - @include retina-sprite ($clothes, dress, 80/20);  
198 - background-color: #fff;  
199 - background-size: 100%;  
200 - }  
201 -  
202 - &.headset {  
203 - @include retina-sprite ($clothes, headset, 80/20);  
204 - background-color: #fff;  
205 - background-size: 100%;  
206 - }  
207 -  
208 - &.lamp {  
209 - @include retina-sprite ($clothes, lamp, 80/20);  
210 - background-color: #fff;  
211 - background-size: 100%;  
212 - }  
213 -  
214 - &.pants {  
215 - @include retina-sprite ($clothes, pants, 80/20);  
216 - background-color: #fff;  
217 - background-size: 100%;  
218 - }  
219 -  
220 - &.shoe {  
221 - @include retina-sprite ($clothes, shoe, 80/20);  
222 - background-color: #fff;  
223 - background-size: 100%;  
224 - }  
225 -  
226 - &.swim-suit {  
227 - @include retina-sprite ($clothes, swim-suit, 80/20);  
228 - background-color: #fff;  
229 - background-size: 100%;  
230 - }  
231 -  
232 - &.under {  
233 - @include retina-sprite ($clothes, under, 80/20);  
234 - background-color: #fff;  
235 - background-size: 100%;  
236 - }  
237 -  
238 - &.watch {  
239 - @include retina-sprite ($clothes, watch, 80/20);  
240 - background-color: #fff;  
241 - background-size: 100%;  
242 - } 174 + &.cloth {
  175 + @include retina-sprite ($clothes, cloth, 80/20);
  176 + background-color: #fff;
  177 + background-size: 100%;
  178 + }
  179 +
  180 + &.dress {
  181 + @include retina-sprite ($clothes, dress, 80/20);
  182 + background-color: #fff;
  183 + background-size: 100%;
  184 + }
  185 +
  186 + &.headset {
  187 + @include retina-sprite ($clothes, headset, 80/20);
  188 + background-color: #fff;
  189 + background-size: 100%;
  190 + }
  191 +
  192 + &.lamp {
  193 + @include retina-sprite ($clothes, lamp, 80/20);
  194 + background-color: #fff;
  195 + background-size: 100%;
  196 + }
  197 +
  198 + &.pants {
  199 + @include retina-sprite ($clothes, pants, 80/20);
  200 + background-color: #fff;
  201 + background-size: 100%;
243 } 202 }
  203 +
  204 + &.shoe {
  205 + @include retina-sprite ($clothes, shoe, 80/20);
  206 + background-color: #fff;
  207 + background-size: 100%;
  208 + }
  209 +
  210 + &.swim-suit {
  211 + @include retina-sprite ($clothes, swim-suit, 80/20);
  212 + background-color: #fff;
  213 + background-size: 100%;
  214 + }
  215 +
  216 + &.under {
  217 + @include retina-sprite ($clothes, under, 80/20);
  218 + background-color: #fff;
  219 + background-size: 100%;
  220 + }
  221 +
  222 + &.watch {
  223 + @include retina-sprite ($clothes, watch, 80/20);
  224 + background-color: #fff;
  225 + background-size: 100%;
  226 + }
  227 + }
  228 +
  229 + .thumb {
  230 + display: inline-block;
  231 + position: relative;
  232 + margin-right: 22rem / $pxConvertRem;
  233 + padding-bottom: 30rem / $pxConvertRem;
  234 +
  235 + &:last-child {
  236 + margin-right: 0;
  237 + }
  238 +
  239 + &.focus .thumb-img {
  240 + border-color: #000;
  241 + }
  242 + }
  243 +
  244 + .thumb-img {
  245 + height: 134rem / $pxConvertRem;
  246 + width: 96rem / $pxConvertRem;
  247 + border: 1px solid transparent;
244 } 248 }
245 249
246 .related-reco-block { 250 .related-reco-block {
@@ -137,7 +137,7 @@ @@ -137,7 +137,7 @@
137 <ul class="info-list"> 137 <ul class="info-list">
138 {{# relatedInfo}} 138 {{# relatedInfo}}
139 <li> 139 <li>
140 - <a href={{url}}> 140 + <a class="clearfix" href={{url}}>
141 <img class="lazy {{#if squareThumb}}square{{/if}}" data-original={{thumb}}> 141 <img class="lazy {{#if squareThumb}}square{{/if}}" data-original={{thumb}}>
142 <span class="title">{{title}}</span> 142 <span class="title">{{title}}</span>
143 <span class="publish-time"> 143 <span class="publish-time">
@@ -56,6 +56,24 @@ class DetailController extends AbstractAction @@ -56,6 +56,24 @@ class DetailController extends AbstractAction
56 'isFew' => true, 56 'isFew' => true,
57 'url' => '' 57 'url' => ''
58 ) 58 )
  59 + ),
  60 + array(
  61 + 'thumb' => 'http://7xidk0.com1.z0.glb.clouddn.com/clothe.png',
  62 + 'type' => 'cloth',
  63 + 'goods' => array(
  64 + 'id' => 1,
  65 + 'thumb' => 'http://img11.static.yhbimg.com/goodsimg/2015/03/02/07/01ebfb219e22770ffb0c2c3a2cbb2b4bef.jpg?imageMogr2/thumbnail/235x314/extent/235x314/background/d2hpdGU=/position/center/quality/90',
  66 + 'name' => 'GAWS DIGI 丛林数码印花拼接卫衣',
  67 + 'price' => 1268,
  68 + 'salePrice' => 589,
  69 + 'tags' => array(
  70 + array(
  71 + 'isNew' => true
  72 + )
  73 + ),
  74 + 'isFew' => true,
  75 + 'url' => ''
  76 + )
59 ) 77 )
60 ) 78 )
61 ) 79 )