09.12 今天主要分享如何用原生JS进行商品页面封装。
一、数据
首先我们需要有一个商品数据,可以看到在这里我将商品简单分为两类:水果蔬菜和生鲜,具体内容不重要。
"goods": [
{
"type": 0,
"title": "水果蔬菜",
"addr": "res/image/fruit-banner.png",
"des": [
{
"id": 0,
"title": "邮政包邮!【土购网】赣南脐橙5斤试吃装 正宗赣南脐橙 酸甜可口",
"price": "19.90",
"name": "正宗赣南脐橙",
"image": "res/image/chengzi.jpg"
},
{
"id": 1,
"title": "九山生姜 2.5kg",
"price": "38.90",
"name": "九山生姜 2.5kg",
"image": "res/image/shengjiang.jpg"
},
{
"id": 2,
"title": "九山生姜 2.5kg",
"price": "38.90",
"name": "九山生姜 2.5kg",
"image": "res/image/shengjiang.jpg"
},
{
"id": 3,
"title": "邮政包邮!【土购网】赣南脐橙5斤试吃装 正宗赣南脐橙 酸甜可口",
"price": "19.90",
"name": "正宗赣南脐橙",
"image": "res/image/chengzi.jpg"
},
{
"id": 4,
"title": "九山生姜 2.5kg",
"price": "38.90",
"name": "九山生姜 2.5kg",
"image": "res/image/shengjiang.jpg"
},
{
"id": 5,
"title": "九山生姜 2.5kg",
"price": "38.90",
"name": "九山生姜 2.5kg",
"image": "res/image/shengjiang.jpg"
},
{
"id": 6,
"title": "邮政包邮!【土购网】赣南脐橙5斤试吃装 正宗赣南脐橙 酸甜可口",
"price": "19.90",
"name": "正宗赣南脐橙",
"image": "res/image/chengzi.jpg"
},
{
"id": 7,
"title": "九山生姜 2.5kg",
"price": "38.90",
"name": "九山生姜 2.5kg",
"image": "res/image/shengjiang.jpg"
},
{
"id": 8,
"title": "九山生姜 2.5kg",
"price": "38.90",
"name": "九山生姜 2.5kg",
"image": "res/image/shengjiang.jpg"
}
]
},
{
"type": 1,
"title": "生鲜",
"addr": "res/image/shengxian-banner.jpg",
"des": [
{
"id": 0,
"title": "1号鲜客 挪威冰鲜三文鱼刺身400g",
"price": "79.00",
"name": "挪威冰鲜三文鱼刺身400g",
"image": "res/image/sanwenyu.jpg"
},
{
"id": 1,
"title": "大连特产鲜活大鲍鱼鲜活海鲜水产活鲜海产",
"price": "128.00",
"name": "大连特产鲜活大鲍鱼",
"image": "res/image/baoyu.jpg"
},
{
"id": 2,
"title": "大连特产鲜活大鲍鱼鲜活海鲜水产活鲜海产",
"price": "128.00",
"name": "大连特产鲜活大鲍鱼",
"image": "res/image/baoyu.jpg"
},
{
"id": 3,
"title": "1号鲜客 挪威冰鲜三文鱼刺身400g",
"price": "79.00",
"name": "挪威冰鲜三文鱼刺身400g",
"image": "res/image/sanwenyu.jpg"
},
{
"id": 4,
"title": "大连特产鲜活大鲍鱼鲜活海鲜水产活鲜海产",
"price": "128.00",
"name": "大连特产鲜活大鲍鱼",
"image": "res/image/baoyu.jpg"
},
{
"id": 5,
"title": "大连特产鲜活大鲍鱼鲜活海鲜水产活鲜海产",
"price": "128.00",
"name": "大连特产鲜活大鲍鱼",
"image": "res/image/baoyu.jpg"
},
{
"id": 6,
"title": "1号鲜客 挪威冰鲜三文鱼刺身400g",
"price": "79.00",
"name": "挪威冰鲜三文鱼刺身400g",
"image": "res/image/sanwenyu.jpg"
},
{
"id": 7,
"title": "大连特产鲜活大鲍鱼鲜活海鲜水产活鲜海产",
"price": "128.00",
"name": "大连特产鲜活大鲍鱼",
"image": "res/image/sanwenyu.jpg"
},
{
"id": 8,
"title": "大连特产鲜活大鲍鱼鲜活海鲜水产活鲜海产",
"price": "128.00",
"name": "大连特产鲜活大鲍鱼",
"image": "res/image/baoyu.jpg"
},
{
"id": 9,
"title": "1号鲜客 挪威冰鲜三文鱼刺身400g",
"price": "79.00",
"name": "挪威冰鲜三文鱼刺身400g",
"image": "res/image/sanwenyu.jpg"
},
{
"id": 10,
"title": "大连特产鲜活大鲍鱼鲜活海鲜水产活鲜海产",
"price": "128.00",
"name": "大连特产鲜活大鲍鱼",
"image": "res/image/baoyu.jpg"
},
{
"id": 11,
"title": "大连特产鲜活大鲍鱼鲜活海鲜水产活鲜海产",
"price": "128.00",
"name": "大连特产鲜活大鲍鱼",
"image": "res/image/baoyu.jpg"
}
]
}
]
二、JS封装
这里我们没有用传统的html布局写法,而是将该部分进行封装。
封装之后的具体效果如上所示。
首先我们要定义一个入口,用于将我们的方法暴露出去。
window.pageTools = window.pageTools || {};
接着采用IIFE方法进行封装,首先定义一个方法来接收数据、页面对应的dom位置和回调函数。
function Goods(datas,selector,callback){
this.datas = datas;
this.selector = $(selector);
this.callback = callback;
this.goods();
}
接着我们来封装渲染到页面的商品页面代码,具体的解释在注释中都有写清楚,这里不多赘述。
Goods.prototype.goods = function() {
// 1.创建一个goods-menu作为大框架
var goodsMenu = $('<ul class="goods-menu"></ul>')
// 将我们定义的goods-menu接到我们的主页dom上
this.selector.append(goodsMenu);
// 2.对拿到的数据进行遍历
this.datas.forEach(function(item) {
// 3.设置水果蔬菜和生鲜的大类
var goodsLi = $('<li class="goods-li"><img src="' + item.addr + '"><h3>' + item.title + '</h3></li>');
// 将两个大类装到goods-menu上
goodsMenu.append(goodsLi);
// 4.设置两个大类底下的小类
var goodsSubMenu = $('<ul class="goods-sub-menu"></ul>')
// 将小类装到大类上
goodsLi.append(goodsSubMenu);
// console.log(item);
// 5.拿到对应大类数据底下的小类数据进行遍历
item.des.forEach(function(info) {
// console.log(info);
// 6.设置每个对应的商品
var goodsSubLi = $('<li class="goods-sub-li"><a href="/view/goods_details.html?type=' + item.type + '&id=' + info.id + '"><img src="' + info.image + '"><h3>' + info.title + '</h3><p>' + info.price + '</p></a></li>')
// 将每个商品放到对应的大类底下
goodsSubMenu.append(goodsSubLi)
})
});
}
接下来是对上述代码每一步具体实现的页面,以及部分控制台输出数据,方便大家理解上述代码。(当然只写了上述的代码是没有办法实现的,因为我们还没将数据和具体dom传进去,这里只是为了方便理解给大家展示一下传完数据和dom之后的结果)
1.创建一个goods-menu作为大框架,将我们定义的goods-menu接到我们的主页dom上
(这里的主页dom是我已经在index.html页面里创建好的)
可以看到goods-menu已经被我们添加进来了,此时页面还没有任何东西,因为我们还没往里加东西。
2.对拿到的数据进行遍历
这里我们在控制台输出一下我们拿到的数据
可以看到我们拿到了两条数据,分别是水果蔬菜和生鲜。
3.设置水果蔬菜和生鲜的大类,将两个大类装到goods-menu上
注意这里我们的代码item.addr
和item.title
,只要仔细看我们之前在控制台拿到的数据就可以直到这里我们分别拿到的值是什么。
var goodsLi = $('<li class="goods-li"><img src="' + item.addr + '"><h3>' + item.title + '</h3></li>');
所以这里我们得到页面如下
4.设置两个大类底下的小类,将小类装到大类上
可以看到dom已经添加,还没有内容。
5.拿到对应大类数据底下的小类数据进行遍历
这里我们将数据下的des进行遍历。
得到控制台数据如下
6.设置每个对应的商品,将每个商品放到对应的大类底下
这里与第三步的本质逻辑相同,最后得到商品页面如下
当然以上只是布局,还需要css对其进行包装,这里就不多讲。
以上的封装完成后,我们还需要通过入口,将其暴露在外。
window.pageTools.Goods = Goods;
完整代码如下
window.pageTools = window.pageTools || {};
;(function(){
// 商品
function Goods(datas,selector,callback){
this.datas = datas;
this.selector = $(selector);
this.callback = callback;
this.goods();
}
Goods.prototype.goods = function() {
var goodsMenu = $('<ul class="goods-menu"></ul>')
this.selector.append(goodsMenu);
this.datas.forEach(function(item) {
var goodsLi = $('<li class="goods-li"><img src="' + item.addr + '"><h3>' + item.title + '</h3></li>');
goodsMenu.append(goodsLi);
var goodsSubMenu = $('<ul class="goods-sub-menu"></ul>')
goodsLi.append(goodsSubMenu);
// console.log(item);
item.des.forEach(function(info) {
console.log(info);
var goodsSubLi = $('<li class="goods-sub-li"><a href="/view/goods_details.html?type=' + item.type + '&id=' + info.id + '"><img src="' + info.image + '"><h3>' + info.title + '</h3><p>' + info.price + '</p></a></li>')
goodsSubMenu.append(goodsSubLi)
})
});
}
window.pageTools.Goods = Goods;
})();
当然,封装完之后我们需要将具体的数据和主页dom传进去,这里我们同样用到IIFE方法进行封装
; (function () {
function Page(url) {
this.loadDate(url).then(function (res) {
// console.log(res);
this.init(res)
}.bind(this))
}
Page.prototype.init = function(data) {
this.goods(data.goods);
}
// 商品详情
Page.prototype.goods = function (goods_datas) {
new pageTools.Goods(goods_datas,'.goods-details',function(){})
}
Page.prototype.loadDate = function (url) {
return new Promise(function (success, fail) {
$.ajax({
type: 'get',
url: url
}).then(function (res) {
success(res)
})
})
}
function main() {
new Page('/res/data/data.json') // 具体路径
}
main();
})();