用H5自带拖拽做出购物车效果的作业题
效果描述: 图片代表物品,图片在有宽高的div上方显示,把图片拖放到设置好的div里面,并且在div里面显示图片的信息:价格,物品名,数量。如果拖放有重复,只是在div里面让物品的数量加1,最后计算出所有拖放物品的价格之和,并且显示在div里面,利用appendChild的的剪贴行,保证在计算价格的时候总是在所计算价格的物品的下一行。
下面是代码:
HTML+CSS布局
<ul id="ul1"> <li draggable="true"> <img src="imgs/1.jpg" > <p>物品1</p> <p>50¥</p> </li> <li draggable="true"> <img src="imgs/2.jpg" > <p>物品2</p> <p>40¥</p> </li> <li draggable="true"> <img src="imgs/3.jpg" > <p>物品3</p> <p>30¥</p> </li> <li draggable="true"> <img src="imgs/4.jpg" > <p>物品4</p> <p>20¥</p> </li> </ul> <div id="div1"> <p> <span class="box2">物品名</span> <span class="box3">物品个数</span> <span class="box1">物品价格</span> </p>
*{margin: 0; padding: 0;} li{list-style: none} #ul1 li{float: left;margin: auto 5px; border: 1px solid #000} #ul1 img{width:270px;height:400px;} #ul1 li p{ text-align:center; border-bottom: 1px solid #000 } #div1{clear: both;border:1px solid ;width:1125px;height: 200px;position: relative} #div1 p{border:1px dashed #ccc} #div1 p span{ margin-left: 200px} .allMoney{float: right}
下面是JS:
物体拖思路,首先是拖拽物体的ondragstart事件下,使用DataTransfer对象过滤被拖动元素。利用DataTransfer对象获取数据值。
var oLi=document.getElementsByTagName('li'); var oDiv=document.getElementById('div1'); var obj={};//利用json查重 var num=0;//计算总钱数 var allMoney=null; var i=0; for(i=0;i<oLi.length;i++){ oLi[i].ondragstart=function(ev){ // this指的是oLi[i], var oP=this.getElementsByTagName('p'); ev.dataTransfer.setData('name',oP[0].innerHTML); ev.dataTransfer.setData('price',oP[1].innerHTML); ev.dataTransfer.setDragImage(this,0,0);//让拖动照片里选中li标签里面的所有内容 }; }
然后是物体放:放的时候应当是创建标签,并设置标签的内容分别为name的值的price的值, countMoney(),是计算总钱数的函数。
oDiv.ondragover=function(){ //阻止默认事件,否则无法ondrop return false }; oDiv.ondrop=function(ev){ //在ondrop事件中getData var name=ev.dataTransfer.getData('name'); var price=ev.dataTransfer.getData('price'); //判断内容是否一致 //原理:建造一个JSON格式,JSON对象的属性没有name的属性(obj[name]!=1),继续造标签, //放odiv里面,并设置obj[name]=1,否则box1的innerHTML+1,原理在else那边写着。 if(obj[name]!=1){ //统一生成p标签 var ap=document.createElement('p'); //先生成box2,里面盛放的是物品的名字 var aspan1=document.createElement('span'); aspan1.className='box2'; aspan1.innerHTML=name; //再生成box3,里面盛放的是物品的价格 var aspan3=document.createElement('span'); aspan3.className='box3'; aspan3.innerHTML=price; //最后生成box1,里面盛放的是物品的个数 var aspan2=document.createElement('span'); aspan2.className='box1'; aspan2.innerHTML=1; //把aspan加到生的p标签里面 ap.appendChild(aspan1); ap.appendChild(aspan2); ap.appendChild(aspan3); //把p标签都加在div里面 oDiv.appendChild(ap); //不重复后,把obj[name]的值设为1 obj[name]=1; countMoney(); return false; } else{ //有重复的物品,他们物品个数会重复加1 //原理:如果是重复的,那么先判断重复的box2的内容和name是否一致,box2里面的 //内容放的是物品的名字为什么要用for语句遍历呢,简单的理解就是name的获取也是根据遍历得到的 //如果一致的话让box1的数值加一即可,注意box1的数值是字符串,必须要转成数值,再加一。 var oBox1=document.getElementsByClassName('box1'); var oBox2=document.getElementsByClassName('box2'); var i=0; for(i=0;i<oBox2.length;i++){ if(oBox2[i].innerHTML==name){ oBox1[i].innerHTML=parseInt(oBox1[i].innerHTML)+1; } } countMoney(); }
计算总钱数的函数,这个函数必须放在ondrop函数里面。
function countMoney(){ //如果没有allMoney的span,那么就生成一个allmoney。 if(!allMoney){ allMoney=document.createElement('div'); allMoney.className='allMoney'; } num+=parseInt(price); allMoney.innerHTML='合计为:'+num+'¥'; oDiv.appendChild(allMoney); //如果有allMoney,就只能它的数值增加就行。 }
总结:我觉得这里面值得注意的有两点点,一是查重,首先是建一个空的json,然后判断json的里是否的有name这个属性,如果有,只是让其的数量的值+1,如果没有没话继续新建child,并置json[name]=1;,二是如何建一个总价格的div标签,并让其innerHTML的值为所有价格总和,这时候就有一个小技巧,就是先判断有没有先建的div标签,没有的话,建立div标签,设置className,如果有只是改变数值,本来oDiv.appendChild(allMoney);应该在if里面,但是为了让每次添加一个物品项,合计价格在物品项下面,就把其放在if外面,利用了appendChild的剪贴性。这两点是我觉得应该注意的和思考的。
这个例子就是我学H5自带拖拽事件学到的知识。