Authored by lore-w

商品列表鼠标事件、业务逻辑解耦

... ... @@ -20,6 +20,6 @@
{{!-- 搜索 --}}
{{#if searchListPage}}
<script>
seajs.use('js/product/list');
seajs.use(['js/product/list', 'js/product/product']);
</script>
{{/if}}
\ No newline at end of file
... ...
... ... @@ -4,5 +4,6 @@ require('./js/common');
require('./js/home/home');
require('./js/product/list');
require('./js/product/product');
module.exports = webYohobuy;
... ...
/**
*Description: 商品自定义事件
*Author: chenglong.wang@yoho.cn
*Date: 2015/12/3
*/
var $ = require('yoho.jquery');
function ProductEvent() {
this.handlers = {};
}
ProductEvent.prototype = {
constructor: ProductEvent,
addHandler: function(type, handler) {
if (typeof this.handlers[type] === 'undefined') {
this.handlers[type] = [];
}
this.handlers[type].push(handler);
},
fire: function(event) {
var handlers,
i;
if (!event.target) {
event.target = this;
}
if (this.handlers[event.type] instanceof Array) {
handlers = this.handlers[event.type];
for (i = 0; i < handlers.length; i++) {
handlers[i](event);
}
}
},
removeHandler: function(type, handler) {
var handlers,
i;
if (this.handlers[type] instanceof Array) {
handlers = this.handlers[type];
for (i = 0; i < handlers.length; i++) {
if (handlers[i] === handler) {
break;
}
}
handlers.splice(i, 1);
}
}
};
module.exports = function($o, rowWidth) {
var pMouseHover = new ProductEvent();
var targetWidth = $o.eq(0).width(),
targetHeight = $o.eq(0).height();
function handleEvent(event) {
var $target,
targetX = 0,
targetY = 0,
rowW = rowWidth,
activeIndex = 0,
$targetDuplicate = '';
switch (event.type) {
case 'mouseenter':
$target = $(this);
$targetDuplicate = $target.clone();
activeIndex = $target.index() + 1;
targetX = (activeIndex % rowW) === 0 ? rowW : activeIndex % rowW;
targetY = Math.ceil(activeIndex / rowW);
pMouseHover.fire({
type: 'MouseEnter',
target: $target,
targetWidth: targetWidth,
targetHeight: targetHeight,
targetX: targetX,
targetY: targetY,
rowWidth: rowW,
activeIndex: activeIndex,
targetDuplicate: $targetDuplicate
});
break;
case 'mouseleave':
pMouseHover.fire({
type: 'MouseLeave'
});
break;
}
}
$o.bind('mouseenter', handleEvent);
//$o.bind('mouseleave', handleEvent);
return pMouseHover;
};
\ No newline at end of file
... ...
... ... @@ -24,13 +24,6 @@ var $brandDefault = $('.brand .default'),
var $brandMoreTxt, $brandMoreIcon;
//商品相关变量
var $goodsContainer = $('.goods-container'),
$goodItem = $goodsContainer.find('.good-info'),
$goodItemWrapper = $goodsContainer.find('.good-item-wrapper'),
$goodInfoMain = $goodsContainer.find('.good-info-main'),
$goodSelectColor = $goodsContainer.find('.good-select-color');
//价格相关变量
var $udPrice = $('.ud-price-range'),
interReg = /^\d+$/,
... ... @@ -328,100 +321,3 @@ $('.senior-sub').on('click', '.multi-select', function() {
}
});
}());
/*
* Description: 商品列表移入效果
* Added by wangchenglong at 2015/12/1
*/
// 构造html
function createColorList(data) {
var colorListStr = '',
len = data.length,
row = 4, //每列ul放4个li
col = Math.ceil(len / row), //需要几**列**ul
i,
j,
index,
ulNum = 0;
for (i = 0; i < col; i++) {
colorListStr += '<ul>';
for (j = 0; j < row; j++) {
index = i * row + j;
if (index === len) {
break;
}
colorListStr +=
'<li>' +
'<a href="' + data[i * row + j].url + '">' +
'<img src="' + data[i * row + j].src + '" />' +
'</a>' +
'</li>';
if (j === row - 1) {
colorListStr += '</ul>';
ulNum++;
}
}
}
if (ulNum < col) {
colorListStr += '</ul>';
}
return colorListStr;
}
//todo
$goodItem.mouseenter(function() {
var $cloneStr,
activeIndex,
X,
left,
Y,
top,
colNum = 5,
itemW = 222,
itemH = 400,
itemMr = 10,
itemMb = 35;
activeIndex = $(this).index() + 1;
X = (activeIndex % colNum) === 0 ? colNum : activeIndex % colNum;
Y = Math.ceil(activeIndex / colNum);
left = (X - 1) * (itemW + itemMr) + 15 - 21;
top = (Y - 1) * (itemH + itemMb) + 25 - 19;
$cloneStr = $(this).clone();
$goodInfoMain.html('');
$goodSelectColor.html('');
$goodItemWrapper.css({
display: 'none'
});
$.ajax({
type: 'GET',
url: '/product/index/productColor',
dataType: 'json'
}).then(function(data) {
$goodInfoMain.append($cloneStr);
$goodSelectColor.append($(createColorList(data)));
});
$goodItemWrapper.css({
left: left,
top: top,
display: 'inline-block'
});
});
$goodItemWrapper.mouseleave(function() {
$goodInfoMain.html('');
$goodSelectColor.html('');
$goodItemWrapper.css({
display: 'none'
});
});
\ No newline at end of file
... ...
/**
*Description: 商品列表页
*Author: chenglong.wang@yoho.cn
*Date: 2015/12/2
*/
var $ = require('yoho.jquery'),
productEvent = require('../common/product-event');
var $goodsContainer = $('.goods-container'),
$goodItem = $goodsContainer.find('.good-info'),
$goodItemWrapper = $goodsContainer.find('.good-item-wrapper'),
$goodInfoMain = $goodsContainer.find('.good-info-main'),
$goodSelectColor = $goodsContainer.find('.good-select-color');
var MouseOver = productEvent($goodItem, 5);
// 构造html
function createColorList(data) {
var colorListStr = '',
len = data.length,
row = 4, //每列ul放4个li
col = Math.ceil(len / row), //需要几**列**ul
i,
j,
index,
ulNum = 0;
for (i = 0; i < col; i++) {
colorListStr += '<ul>';
for (j = 0; j < row; j++) {
index = i * row + j;
if (index === len) {
break;
}
colorListStr +=
'<li>' +
'<a href="' + data[i * row + j].url + '">' +
'<img src="' + data[i * row + j].src + '" />' +
'</a>' +
'</li>';
if (j === row - 1) {
colorListStr += '</ul>';
ulNum++;
}
}
}
if (ulNum < col) {
colorListStr += '</ul>';
}
return colorListStr;
}
MouseOver.addHandler('MouseEnter', function(event) {
var itemMr = 10, //list的右边距
itemMb = 35, //list的下边距
wrapperX = (event.targetX - 1) * (event.targetWidth + itemMr) - 21,
wrapperY = (event.targetY - 1) * (event.targetHeight + itemMb) + 25 - 19;
$goodInfoMain.html('');
$goodSelectColor.html('');
$goodItemWrapper.css({
display: 'none'
});
$.ajax({
type: 'GET',
url: '/product/index/productColor',
dataType: 'json'
}).then(function(data) {
$goodInfoMain.append(event.targetDuplicate);
$goodSelectColor.append($(createColorList(data)));
});
$goodItemWrapper.css({
left: wrapperX,
top: wrapperY,
display: 'inline-block'
});
});
$goodItemWrapper.mouseleave(function() {
$goodInfoMain.html('');
$goodSelectColor.html('');
$goodItemWrapper.css({
display: 'none'
});
});
... ...
var jQuery = require('jquery');
var jQuery = require('yoho.jquery');
(function($) {
$.extend({
... ...
... ... @@ -74,4 +74,4 @@ a:focus {
margin-right: auto;
}
@import "home/index", "product/index";
\ No newline at end of file
@import "home/index", "product/index";
... ...
@import "search", "list", "filter-box", "sort-pager";
\ No newline at end of file
@import "search", "list", "filter-box", "sort-pager";
.products-page {
.filter-box {
border: 1px solid #dfdfdf;
}
.section {
padding: 10px 15px;
font-size: 14px;
border-top: 1px solid #dfdfdf;
&:first-child {
border-top: none;
background: #eaeceb;
}
}
.title {
float: left;
width: 90px;
line-height: 30px;
}
.attr-content {
margin-left: 90px;
}
.multi-select {
display: inline-block;
width: 60px;
height: 18px;
line-height: 18px;
border: 1px solid #000;
text-align: center;
cursor: pointer;
}
.attr {
display: block;
float: left;
padding: 0 10px;
margin-right: 30px;
line-height: 30px;
cursor: pointer;
&:first-child {
margin-left: 0;
}
-moz-user-select: none;
}
.checked-conditions {
line-height: 30px;
.tag {
display: block;
float: left;
padding: 0 10px;
margin-right: 30px;
background: #000;
color: #fff;
cursor: pointer;
}
.color-block {
height: 14px;
width: 14px;
border: 1px solid #fff;
margin-bottom: -3px;
}
.clear-checked {
color: #999;
float: right;
}
}
.sort-sub-wrap {
width: 100%;
.sort-sub {
padding: 15px 0;
}
}
.brand {
position: relative;
.attr {
box-sizing: border-box;
width: 20%;
margin: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.attr-content {
max-width: 900px;
}
.brand-opt {
position: absolute;
right: 20px;
top: 15px;
}
.brand-more {
margin-right: 20px;
cursor: pointer;
}
.brands-index {
float: left;
line-height: 30px;
span {
margin: 0 5px;
cursor: pointer;
-moz-user-select: none;
&:first-child {
margin-left: 10px;
}
}
}
.brand-search {
float: left;
height: 18px;
line-height: 18px;
border: 1px solid #b0b0b0;
margin-top: 5px;
margin-left: 15px;
input {
float: left;
border: none;
width: 100px;
height: 18px;
padding: 0;
}
.btn {
display: inline-block;
width: 55px;
height: 18px;
background: #b0b0b0;
color: #fff;
text-align: center;
cursor: default;
}
}
.panel-body {
padding: 15px 20px;
margin-top: 5px;
background: #f4f7f6;
min-height: 30px;
border: 1px solid #000;
}
}
.btns {
display: none;
margin-top: 10px;
text-align: center;
}
.multi .btns {
display: block;
}
.multi-select-ok, .multi-select-cancel {
width: 55px;
height: 24px;
border: none;
background: #000;
color: #fff;
font-size: 15px;
margin-right: 15px;
cursor: pointer;
&.dis {
background: #ccc;
}
}
.ud-price-range {
margin-top: 2px;
}
.limit {
height: 22px;
width: 42px;
border: 1px solid #ccc;
padding: 0;
}
.price-sep {
margin: 0 5px;
}
.price-sure {
height: 24px;
width: 44px;
border: 1px solid #e0e0e0;
background: #fff;
color: #666;
margin-left: 10px;
}
.color-block {
display: inline-block;
height: 22px;
width: 22px;
border: 1px solid #ccc;
margin-bottom: -6px;
margin-right: 5px;
}
.senior {
padding-bottom: 6px;
.attr-content {
position: relative;
}
}
.senior-attr-wrap {
position: relative;
}
.senior-attr-wrap > .attr:hover,
.senior-attr-wrap > .attr.hover {
> .iconfont {
visibility: hidden;
}
.senior-up-icon {
visibility: visible;
}
}
.senior-sub {
box-sizing: border-box;
position: absolute;
padding: 15px 0;
left: 0;
right: 0;
top: 39px;
background: #fff;
border: 1px solid #eaeceb;
ul {
max-width: 950px;
}
&.multi .multi-select {
display: none;
}
.multi-select {
position: absolute;
top: 20px;
right: 15px;
}
}
.senior-up-icon {
width: 100%;
height: 9px;
z-index: 1;
margin-left: -11px;
visibility: hidden;
background: image-url('product/senior-up.png') no-repeat;
background-position-x: 50%;
}
.checkbox {
display: none;
}
.multi .checkbox {
display: inline;
}
.opt-banner {
height: 48px;
background: #f5f7f6;
line-height: 48px;
margin: 10px 0;
.sort-type,
.checks {
color: #ccc;
font-size: 14px;
padding: 0 10px;
.iconfont {
font-size: 14px;
}
&.active,
&.checked {
color: #000;
}
}
.pager-wrap {
float: right;
padding: 15px 0;
}
.line-count {
float: left;
padding: 3px 1px 3px 3px;
border: 1px solid #ccc;
margin-right: 10px;
span {
float: left;
width: 5px;
height: 10px;
background: #ccc;
margin-right: 2px;
}
&.active {
border-color: #222;
span {
background: #222;
}
}
}
.page-count {
position: relative;
height: 18px;
float: left;
font-size: 12px;
line-height: 18px;
> span {
float: left;
display: block;
width: 42px;
height: 10px;
line-height: 10px;
padding: 3px;
border: 1px solid #ccc;
color: #222;
cursor: pointer;
margin-right: 10px;
}
.iconfont {
font-size: 14px;
color: #ccc;
float: right;
}
> ul {
position: absolute;
display: none;
width: 42px;
padding: 0 3px;
border-left: 1px solid #ccc;
border-right: 1px solid #ccc;
}
li {
border-bottom: 1px solid #ccc;
}
a {
display: block;
width: 100%;
}
}
.pager {
float: left;
font-size: 14px;
line-height: 15px;
margin: 0 20px;
.dis-icon {
color: #e6e6e6;
}
i {
color: #f00;
}
}
}
}
\ No newline at end of file
... ...
/*
*Description: 商品列表
*Author: chenglong.wang@yoho.cn
*Date: 2015/12/1
*/
.product-search-page {
/*商品列表
*Added by wangchenglong at 2015/12/1
*/
//todo
.goods-container {
height: auto;
padding: 25px 15px 0 15px;
overflow: hidden;
padding: 25px 0 0 0;
position: relative;
width: 1150px + 10px;
width: 1150px + 10px;//每列增加右边距
//标签
.tag-container {
... ... @@ -153,67 +158,5 @@
margin-right: 10px;
}
}
//每行六个商品
&.six-per-line {
.good-info {
height: 400px; //todo
margin-bottom: 35px;
width: 222px;
//图片
.good-detail-img {
width: 100%;
height: 300px;
position: relative;
.good-thumb, img.lazy {
display: block;
overflow: hidden;
width: 100%;
height: 100%;
}
.few-tag {
width: 100%;
position: absolute;
left: 0;
height: 16px;
line-height: 16px;
background: #ffac5b;
color: #fff;
font-size: 12px;
text-align: center;
bottom: 0;
}
}
//文本
.good-detail-text {
color: #222;
font-size: 12px;
text-align: center;
> a {
margin-top: 16px;
line-height: 1.5;
display: block;
}
> .price {
margin-top: 10px;
}
}
.col-btn {
position: absolute;
top: 15px;
right: 15px;
color: #ccc;
font-size: 12px;
display: none;
}
}
}
}
//商品列表END
}
\ No newline at end of file
... ...