购物车代码封装之前和之后的2个问题,希望老师能看完js代码后从实现效果原理的角度帮我分析下

购物车代码封装之前和之后的2个问题,希望老师能看完js代码后从实现效果原理的角度帮我分析下

HTML:

<div class="cart dropdown" data-active="cart" data-load="json/index.json">
	<div class="dropdown-toggle transition">
		<i class="gouwu-tubiao iconfont">&#xe689;</i><span class="gouwu">购物车</span><span class="jiange">|</span><span class="geshu">18</span><i class="dropdown-arrow icon-xjiantou iconfont transition"></i>
	</div>
	<div class="dropdown-layer">
		<div class="dropdown-loading"></div>
		<!--<i class="iconfont layer1-icon">&#xe608;</i><span class="layer1-zhuti">购物车里还没有商品<br>赶紧去选购吧</span>-->
		
		<!--<div class="layer-top">最新加入的商品</div>
		<div class="layer-connent">
			<div class="layer-box">
				<div class="layer-item clearfixed">
					<img class="tupian fl" src="img/cart/1.png">
					<div class="shanchu fr">X</div>
					<div class="wenzi">adidas 阿迪达斯 训练 男子<br>¥335*1</div>
				</div>
				……
			</div>
		</div>
		<div class="layer-bottom clearfixed">
			<div class="fl">共<span id="jianshu">15</span>件商品</div>
			<div class="fl">共计¥ <span id="qianshu">0</span>.00</div>
			<div>去购物车</div>
		</div>-->
		
	</div>
</div>

css:

.cart{width: 128px;height: 12px;background-color: #f01414;padding: 15px;cursor: pointer;
	position: fixed;left: calc(50% - 79px);top: 20%;}
	.cart .dropdown-toggle{color: white;line-height: 12px;font-size: 12px;}
	.gouwu{margin-left: 14px;}
	.jiange,.geshu{margin-left: 10px;}
	.icon-xjiantou{margin-left: 8px;}
	.cart .dropdown-layer{background-color: white;box-shadow: 0px 5px 5px 5px #ccc;width: 320px;right: 0px;top: 42px;}
	/**/
	.cart .layer1-icon{line-height: 120px;color: #d9dde1;font-size: 30px;text-indent: 80px;display: inline-block;}
	.cart .layer1-zhuti{font-size: 11px;line-height: 20px;color: #cbb2ab;position: absolute;top: 40px;left: 126px;}
	/**/
	.cart .layer-top{margin: 20px 30px 0px 24px;padding-bottom: 20px;border-bottom: 1px solid #d9dde1;color: #601142;}
	.cart .layer-connent{width: 296px;height: 325px;margin-left: 24px;overflow: auto;}
	.cart .layer-box{width: 266px;height: 975px;}
	.cart .layer-item{width: 266px;height: 64px;border-bottom: 1px solid #d9dde1;position: relative;}
	.cart .layer-item > .tupian{display: block;margin-top: 8px;}
	.cart .layer-item > .shanchu{font-size: 14px;margin-top: 8px;margin-right: 14px;}
	.cart .layer-item > .wenzi{position: absolute;top: 8px;left: 56px;font-size: 14px;line-height: 22px;}
	.cart .layer-bottom{height: 64px;margin-left: 24px;margin-right: 28px;position: relative;font-size: 12px;}
	.cart .layer-bottom div:first-of-type{margin-left: 10px;line-height: 64px;}
	.cart .layer-bottom div:nth-of-type(2){margin-left: 10px;line-height: 64px;}
	.cart .layer-bottom div:last-of-type{position: absolute;top: 16px;right: 0;
		width: 80px;height: 36px;background-color: red;color: white;text-align: center;line-height: 36px;border-radius: 4px;}
	/*交互*/
	.cart-active{background-color: white;box-shadow: 0px 0px 5px 5px #ccc;}
	.cart-active .dropdown-toggle{color: #f01414;}
	.icon-xjiantou.dropdown-arrow.transition{transition: transform 1s;}

公共css和transition模块、showHide模块跟老师一样

dropdown模块不一样的地方:(第一个问题中的代码在这里)

this.$layer.on("show shown hide hidden",function(event){
			self.$elem.trigger('dropdown-'+event.type,function(){
				self.$layer.height("auto")//为了购物车而添加
				.height(self.$layer.height());
			});//发送消息
		});

问题的重点:

  1. 没有封装之前的代码为什么需要更新下拉层的高度,否则当数据为空时显示高度为72px,而应该是120px。而封装之后的代码不需要更新下拉层的高度就效果是对的,请问是什么原因,不是很理解(起作用的代码:self.$layer.height("auto").height(self.$layer.height());我知道代码的含义是开始给下拉层设置高度为auto,然后再获取下拉层高度用height方法添加上,这样就是内容撑起来的高度,但是不知道为什么封装前后一个需要,一个不需要)

  2. $this.data('loaded',true);为什么封装之前写在getJSON里面的最后,而封装之后老师写在了getJSON外面的前面,为了什么效果如此改变代码的位置?

    需要老师看的代码:



  3. $('.cart').on('dropdown-show',function(updataLayer){
            loadOnce($(this), function($elem, data,updataLayer) {
                buildCartItem($elem,data,function(){
    				updateCart($elem, data);
    			},updataLayer);
            });
        }).dropdown({
            css3: true,
            js: false
        });    
    
    function buildCartItem($elem,data,updataLayer) {
    	var $layer=$elem.find('.dropdown-layer'),
    		html="";
    	if(data.length==0){
    		setTimeout(function(){
    			html='<i class="iconfont layer1-icon">&#xe608;</i><span class="layer1-zhuti">购物车里还没有商品<br>赶紧去选购吧</span>';
    			$layer.html(html);
    			updataLayer();
    		},1000);
    		return;
    	   }else{
    		setTimeout(function(){//模拟服务器延迟
    			html+='<div class="layer-top">最新加入的商品</div><div class="layer-connent"><div class="layer-box">';
    			for(var i=0;i<data.length;i++){
    				html+='<div class="layer-item clearfixed"><img class="tupian fl" src="'+data[i].src+'"><div class="shanchu fr">X</div><div class="wenzi">'+data[i].wenzi+'<br>¥'+data[i].price+'&nbsp;X&nbsp;'+data[i].num+'</div></div>';
    			}
    			html+='</div></div><div class="layer-bottom clearfixed"><div class="fl">共<span class="jianshu">45</span>件商品</div><div class="fl">共计¥ <span class="qianshu">0</span>.00</div><div>去购物车</div></div>';
    			$layer.html(html);
    			updataLayer();
    		},1000);
    	   }
    }
    function loadOnce($elem,success,updataLayer){
    	var dataLoad=$elem.data('load');
    	if(!dataLoad)return;
    	if(!$elem.data('loaded')){
    		$elem.data('loaded',true);//这里
    		$.getJSON(dataLoad)
    		.done(function(data){
    			if(typeof success==='function'){
    				setTimeout(function(){
    					success($elem,data);
    					updataLayer();
    				},200);
    			}
    		}).fail(function(){
    			$elem.data('loaded',false);
    		});
    	 }
    }
    function updateCart($elem, data) {
    	var $cartNum = $elem.find('.geshu'),
    		$cartTotalNum = $elem.find('.jianshu'),
    		$cartTotalPrice = $elem.find('.qianshu'),
    		dataNum = data.length,
    		totalNum = 0,
    		totalPrice = 0;
    
    	if (dataNum === 0) {// no goods
    		$cartNum.html("0");
    		return;
    	}else{
    		for (var i = 0; i < dataNum; i++) {
    			totalNum += +data[i].num;
    			totalPrice += +data[i].num * +data[i].price;
    		}
    		$cartNum.html(totalNum);
    		$cartTotalNum.html(totalNum);
    		$cartTotalPrice.html(totalPrice);
    	}
    	
    }
  4. $('.cart').on('dropdown-show',function(event,updataLayer){
    	var $this=$(this);
    	var dataLoad=$this.data('load');
    	if(!dataLoad)return;
    	if(!$this.data('loaded')){
    		var $layer=$this.find('.dropdown-layer'),
    			html="",
    			count=0,
    			jiage=0;
    		//$layer.html('<div class="dropdown-loading"></div>');
    		$.getJSON(dataLoad,function(data){
    			if(data.length==0){
    			    setTimeout(function(){
    					html='<i class="iconfont layer1-icon">&#xe608;</i><span class="layer1-zhuti">购物车里还没有商品<br>赶紧去选购吧</span>';
    					$layer.html(html);
    					updataLayer();
    				},1000);
    				return;
    			   }else{
    				setTimeout(function(){//模拟服务器延迟
    					html+='<div class="layer-top">最新加入的商品</div><div class="layer-connent"><div class="layer-box">';
    					for(var i=0;i<data.length;i++){
    						html+='<div class="layer-item clearfixed"><img class="tupian fl" src="'+data[i].src+'"><div class="shanchu fr">X</div><div class="wenzi">'+data[i].wenzi+'<br>¥'+data[i].price+'</div></div>';
    						count++;
    						jiage+=Number(data[i].price);
    					}
    					html+='</div></div><div class="layer-bottom clearfixed"><div class="fl">共<span class="jianshu">'+count+'</span>件商品</div><div class="fl">共计¥ <span class="qianshu">'+jiage+'</span>.00</div><div>去购物车</div></div>';
    					$layer.html(html);
    					updataLayer();
    				},1000);
    			   }
    			$this.data('loaded',true);//这里
    		});
    	   }
    });

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

2回答
好帮手慕慕子 2020-02-16 10:19:56

同学你好,对于你的问题解答如下:

  1. 同学粘贴的代码,与“星星老师”给出的示例代码不一样,建议:同学仔细查看老师给出的建议,并参考修改,浏览器可能存在缓存问题,导致修改后的效果没有实现,保存文件后,可以清除浏览器缓存测试一下。

    http://img1.sycdn.imooc.com//climg/5e48a46509168f6013941312.jpg

  2. 老师这边测试,是需要添加的。

    示例:使用slideLeftRight动画效果,下拉层的宽度实现有问题,如下:

    http://img1.sycdn.imooc.com//climg/5e48a6810993470302100474.jpg

    建议:同学添加self.$layer.width("auto").width(self.$layer.width());让代码更加严谨,也保证效果实现是正确的。

如果我的回答帮助到了你,欢迎采纳,祝学习愉快~

好帮手慕星星 2020-02-15 20:00:41

同学你好,问题解答如下:

1、封装之后不需要更新下拉层高度是因为没有使用slideUpDown动画

http://img1.sycdn.imooc.com//climg/5e47d86709b7d4a105880242.jpg

昨天老师测试可能有点问题。今天重复测试了很多遍,就是动画的问题。没有使用这个动画,默认是fade

http://img1.sycdn.imooc.com//climg/5e47d8e109179c8606560037.jpg

所以不存在下拉层更新的问题,会直接显示出来。

如果用了slideUpDown动画,仍然存在高度问题。需要传参updateLayer,只传一个地方就可以

http://img1.sycdn.imooc.com//climg/5e47dc3f09ef1a9b07120240.jpg

http://img1.sycdn.imooc.com//climg/5e47dc4e09c61fc005820460.jpg

loadOnce中就可以不传入了。

2,放在获取数据前后都是可以的,只不过封装的代码中放在了前面,但是如果获取数据失败了就更新为false了

http://img1.sycdn.imooc.com//climg/5e47dd49093975b605040330.jpg

多了一步操作而已。

祝学习愉快!

  • 提问者 迷失的小麦 #1
    $('.cart').on('dropdown-show',function(updataLayer){ loadOnce($(this), function($elem,data) { buildCartItem($elem,data,function(){ updateCart($elem, data); updataLayer(); }); }); }).dropdown({ css3: true, js: false, animation:'fadeSlideUpDown' });请问是这样吗?好像不太对
    2020-02-15 20:28:33
  • 提问者 迷失的小麦 #2
    请问是否需要添加self.$layer.width("auto").width(self.$layer.width());防止左右动画显示显示不全,可是我测试的效果是不需要更新下拉层的宽度也能实现效果,这是为什么?
    2020-02-15 20:42:03
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
2.组件化网页开发
  • 参与学习           人
  • 提交作业       1121    份
  • 解答问题       14456    个

本阶段在运用JS实现动态网页开发的基础上,带你深入理解企业开发核心思想,完成一个企业级网页的开发,体验前端工程师的成就感。

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师