效果描述: 圖片代表物品,圖片在有寬高的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自帶拖拽事件學到的知識。