自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一步步教你如何用HTML 5拖拽功能打造購物車

譯文
開發(fā) 前端
在本文中,將指導(dǎo)讀者認(rèn)識 HTML 5中的拖拽功能,并且使用它來打造一款基本的購物車。這個購物車很簡單,我們只往其中放置一件商品然后檢查是否已有商品了,如果已經(jīng)存在同樣的商品,則更 新其數(shù)量和價格。本文要求讀者有初步的HTML 5基礎(chǔ)知識和一定基礎(chǔ)的Javascript知識即可。

在***的HTML 5標(biāo)準(zhǔn)中,為***的各類瀏覽器帶來了拖拽功能。這意味著現(xiàn)在可以不通過其他框架如jQuery的輔助就能在頁面上拖拽各種元素。在本文中,將指導(dǎo)讀者認(rèn)識 HTML 5中的拖拽功能,并且使用它來打造一款基本的購物車。這個購物車很簡單,我們只往其中放置一件商品然后檢查是否已有商品了,如果已經(jīng)存在同樣的商品,則更 新其數(shù)量和價格。本文要求讀者有初步的HTML 5基礎(chǔ)知識和一定基礎(chǔ)的Javascript知識即可。

開始

首先我們需要設(shè)計購物車的基礎(chǔ)結(jié)構(gòu)和準(zhǔn)備一系列的商品。為了簡單演示使用了各類商品,這里只是使用HTML 5中的data_*屬性(可參考https://developer.mozilla.org/en-US/docs/Web/Guide/HTML /Using_data_attributes),為各個商品添加了價格。簡單來說,data_屬性是讓用戶可以為某些標(biāo)簽存儲一些額外的數(shù)據(jù)信息。代碼如下所示:

  1. <section id="cart" class="shopping-cart"> 
  2.     <ul> 
  3.     </ul> 
  4.     <span class="total">0.00</span> 
  5. </section> 
  6. <section id="products" class="products"> 
  7.     <ul> 
  8.         <li id="product-1" data-price="2.00"><span>Product 1</span></li> 
  9.         <li id="product-2" data-price="3.00"><span>Product 2</span></li> 
  10.         <li id="product-3" data-price="2.99"><span>Product 3</span></li> 
  11.         <li id="product-4" data-price="3.50"><span>Product 4</span></li> 
  12.         <li id="product-5" data-price="4.25"><span>Product 5</span></li> 
  13.         <li id="product-6" data-price="6.75"><span>Product 6</span></li> 
  14.         <li id="product-7" data-price="1.99"><span>Product 7</span></li> 
  15.     </ul> 
  16. </section> 

由于本文是主要講解使用Javascript搭配HTML 5的新功能,因此不會使用大家常用的jQuery。下面編寫addEvent事件,代碼如下:

  1. function addEvent(element, event, delegate ) { 
  2.     if (typeof (window.event) != 'undefined' && element.attachEvent) 
  3.         element.attachEvent('on' + event, delegate); 
  4.     else  
  5.         element.addEventListener(event, delegate, false); 

我們將使用的***個事件是readystatechange 。該事件在當(dāng)文檔的狀態(tài)發(fā)生改變的時候觸發(fā),我們期望將其狀態(tài)設(shè)置為“complete”,直到附加上剩余的事件和邏輯代碼。這個跟jQuery中的.ready事件類似。代碼如下:

  1. addEvent(document, 'readystatechange', function() { 
  2.     if ( document.readyState !== "complete" )  
  3.         return true; 
  4. }); 

對DOM查詢

在HTML 5標(biāo)準(zhǔn)中,DOM的選擇器方面也進(jìn)行了更新,其中新增的功能中最有用的方法就是querySelectorAll。這個方法允許用戶使用更復(fù)雜的css樣式選擇器(有點(diǎn)象jQuery)去查詢頁面元素。這比舊有的通過class和ID去進(jìn)行查詢簡單些。

下面是其中一個例子:

  1. var items = document.querySelectorAll("section.products ul li"); 
  2. var cart = document.querySelectorAll("#cart ul")[0]; 

這里,首先是分別使用items和cart變量獲得商品列表和購物車列表,留作稍候使用。可以看到,上面通過querySelectorAll的方 法比以往更加方便了。既然已經(jīng)有了產(chǎn)品的列表,那么我們將實(shí)現(xiàn)拖拽功能并且當(dāng)產(chǎn)品被拖拽的時候,必須要有相關(guān)的事件進(jìn)行監(jiān)聽。為了實(shí)現(xiàn)這個目的,將循環(huán)遍 歷商品列表并且使用setAttribute方法設(shè)置draggable屬性為true,這里并且要為每個商品都添加dragstart事件。代碼如下:

  1. for (var i = 0; i < items.length; i++) { 
  2.     var item = items[i]; 
  3.     item.setAttribute("draggable", "true"); 
  4.     addEvent(item, 'dragstart', onDrag); 
  5. }; 

在上面的代碼中,請注意將dragstart方法委托定義為onDrag。這個方法的目的是設(shè)置拖拽的選項(xiàng)并且保存元素的id留作稍候通過使用 dataTransfer.setData方法獲得數(shù)據(jù)。dataTransfer事件對象允許我們指定默認(rèn)的拖拽動作的效果。默認(rèn)是既復(fù)制并移動,但這 里我們強(qiáng)制令其為只移動元素。代碼如下:

  1. function onDrag(event){ 
  2.     event.dataTransfer.effectAllowed = "move"
  3.     event.dataTransfer.dropEffect = "move"
  4.     var target = event.target || event.srcElement; 
  5.     var success = event.dataTransfer.setData('Text', target.id); 

#p#

設(shè)計購物車

我們先來看下設(shè)計的購物車大概是什么樣子的,如下圖:

看上去樣子不大漂亮,但這個并不影響我們的示例教學(xué)用??梢钥吹接脩艨梢酝侠赑roduct List中的商品到上面的購物車區(qū)域中。

默認(rèn)元素是不接收drop事件的,因此為了能讓某個元素能接收到拖拽的事件消息,我們要重寫默認(rèn)的行為。為了實(shí)現(xiàn)這個目的,使用了onDragOver方法。代碼如下,所做的其實(shí)是阻止默認(rèn)的dragover和dragenter事件行為:

  1. function onDragOver(event){ 
  2.     if(event.preventDefault) event.preventDefault(); 
  3.     if (event.stopPropagation) event.stopPropagation(); 
  4.     else event.cancelBubble = true
  5.     return false; 
  6. addEvent(cart, 'dragover', onDragOver);

接下來,我們要往購物車中增加商品了。只需要使用dataTransfer.getData方法從dataTransfer對象中取出id的值,有了id的值就可以從商品列表中找到商品。但要注意的是在往購物車中放商品前要檢查該商品是否已經(jīng)放置在里面了,

檢查的方法很簡單,只需要使用querySelectorAll方法就可以了,代碼如下:

  1. var exists = document.querySelectorAll("#cart ul li[data-id='" + id + "']"); 

接下來就很容易根據(jù)變量exists去判斷是否購物車中已經(jīng)存在商品,代碼如下:

  1. if(exists.length > 0){ 
  2.     updateCartItem(exists[0]); 
  3. } else { 
  4.     addCartItem(item, id); 
  5. }

 在上面的代碼中,如果購物車中不包含任何商品,則調(diào)用下面的代碼addCartItem。

  1. function addCartItem(item, id) { 
  2.     var clone = item.cloneNode(true); 
  3.     clone.setAttribute('data-id', id); 
  4.     clone.setAttribute('data-quantity', 1); 
  5.     clone.removeAttribute('id'); 
  6.      
  7.     var fragment = document.createElement('span'); 
  8.     fragment.setAttribute('class', 'quantity'); 
  9.     fragment.innerHTML = ' x 1'
  10.     clone.appendChild(fragment);     
  11.      
  12.     fragment = document.createElement('span'); 
  13.     fragment.setAttribute('class', 'sub-total'); 
  14.     clone.appendChild(fragment);                     
  15.     cart.appendChild(clone); 

如果購物車中不包含某件商品,則addCartItem方法中要做的事是克隆當(dāng)前的商品項(xiàng)?,F(xiàn)在可以指定的data-*的值。首先在克隆后的結(jié)點(diǎn)中,設(shè)置的是data-id結(jié)點(diǎn),然后設(shè)置data-quantity屬性為1并移除id屬性(id屬性在頁面中是唯一的)。然后我們增加兩個新的span到列表項(xiàng)中,這是用來顯示小計項(xiàng)和產(chǎn)品的數(shù)量的。下圖是從商品列表中拖拉到購物車中的情景:

更新購物車中的商品

如果一個商品已經(jīng)在購物車中存在了,我們將要增加其數(shù)量,其中我們顯示給用戶的方式是單價*數(shù)量,因此,我們使用 getAttribute方法就可以獲得當(dāng)前的數(shù)量并且對其進(jìn)行增加的操作,代碼如下:

  1. function updateCartItem(item){ 
  2.     var quantity = item.getAttribute('data-quantity'); 
  3.     quantity = parseInt(quantity) + 1 
  4.     item.setAttribute('data-quantity', quantity); 
  5.     var span = item.querySelectorAll('span.quantity'); 
  6.     span[0].innerHTML = ' x ' + quantity; 

#p#

更新總價格

一旦購物車的商品數(shù)量增加了,我們就要重新計算總價格。這里我們再次使用了

querySelectorAll功能。我們只需要遍歷購物車中的每一個商品并重新計算價格就可以了,這里是取了兩位小數(shù)位。

  1. function updateCart(){ 
  2.     var total = 0.0; 
  3.     var cart_items = document.querySelectorAll("#cart ul li") 
  4.     for (var i = 0; i < cart_items.length; i++) { 
  5.         var cart_item = cart_items[i]; 
  6.         var quantity = cart_item.getAttribute('data-quantity'); 
  7.         var price = cart_item.getAttribute('data-price'); 
  8.          
  9.         var sub_total = parseFloat(quantity * parseFloat(price)); 
  10.         cart_item.querySelectorAll("span.sub-total")[0].innerHTML = " = " + sub_total.toFixed(2); 
  11.          
  12.         total += sub_total; 
  13.     } 
  14.      
  15.     document.querySelectorAll("#cart span.total")[0].innerHTML = total.toFixed(2); 

從下圖中可以看到當(dāng)拖拽多個商品到購物車中,商品的總價格是會增加的:

 

***我們總體看下所有的Javascript代碼如下所示。

  1. function addEvent(element, event, delegate ) { 
  2.     if (typeof (window.event) != 'undefined') 
  3.         element.attachEvent('on' + event, delegate); 
  4.     else  
  5.        element.addEventListener(event, delegate, false); 
  6.  
  7. addEvent(document, 'readystatechange', function() { 
  8.     if ( document.readyState !== "complete" )  
  9.         return true; 
  10.          
  11.     var items = document.querySelectorAll("section.products ul li"); 
  12.     var cart = document.querySelectorAll("#cart ul")[0]; 
  13.      
  14.     function updateCart(){ 
  15.         var total = 0.0; 
  16.         var cart_items = document.querySelectorAll("#cart ul li") 
  17.         for (var i = 0; i < cart_items.length; i++) { 
  18.             var cart_item = cart_items[i]; 
  19.             var quantity = cart_item.getAttribute('data-quantity'); 
  20.             var price = cart_item.getAttribute('data-price'); 
  21.              
  22.             var sub_total = parseFloat(quantity * parseFloat(price)); 
  23.             cart_item.querySelectorAll("span.sub-total")[0].innerHTML = " = " + sub_total.toFixed(2); 
  24.              
  25.             total += sub_total; 
  26.         } 
  27.          
  28.         document.querySelectorAll("#cart span.total")[0].innerHTML = total.toFixed(2); 
  29.     } 
  30.      
  31.     function addCartItem(item, id) { 
  32.         var clone = item.cloneNode(true); 
  33.         clone.setAttribute('data-id', id); 
  34.         clone.setAttribute('data-quantity', 1); 
  35.         clone.removeAttribute('id'); 
  36.          
  37.         var fragment = document.createElement('span'); 
  38.         fragment.setAttribute('class', 'quantity'); 
  39.         fragment.innerHTML = ' x 1'
  40.         clone.appendChild(fragment);     
  41.          
  42.         fragment = document.createElement('span'); 
  43.         fragment.setAttribute('class', 'sub-total'); 
  44.         clone.appendChild(fragment);                     
  45.         cart.appendChild(clone); 
  46.     } 
  47.      
  48.     function updateCartItem(item){ 
  49.         var quantity = item.getAttribute('data-quantity'); 
  50.         quantity = parseInt(quantity) + 1 
  51.         item.setAttribute('data-quantity', quantity); 
  52.         var span = item.querySelectorAll('span.quantity'); 
  53.         span[0].innerHTML = ' x ' + quantity; 
  54.     } 
  55.      
  56.     function onDrop(event){             
  57.         if(event.preventDefault) event.preventDefault(); 
  58.         if (event.stopPropagation) event.stopPropagation(); 
  59.         else event.cancelBubble = true
  60.          
  61.         var id = event.dataTransfer.getData("Text"); 
  62.         var item = document.getElementById(id);             
  63.                      
  64.         var exists = document.querySelectorAll("#cart ul li[data-id='" + id + "']"); 
  65.          
  66.         if(exists.length > 0){ 
  67.             updateCartItem(exists[0]); 
  68.         } else { 
  69.             addCartItem(item, id); 
  70.         } 
  71.          
  72.         updateCart(); 
  73.          
  74.         return false; 
  75.     } 
  76.      
  77.     function onDragOver(event){ 
  78.         if(event.preventDefault) event.preventDefault(); 
  79.         if (event.stopPropagation) event.stopPropagation(); 
  80.         else event.cancelBubble = true
  81.         return false; 
  82.     } 
  83.  
  84.     addEvent(cart, 'drop', onDrop); 
  85.     addEvent(cart, 'dragover', onDragOver); 
  86.      
  87.     function onDrag(event){ 
  88.         event.dataTransfer.effectAllowed = "move"
  89.         event.dataTransfer.dropEffect = "move"
  90.         var target = event.target || event.srcElement; 
  91.         var success = event.dataTransfer.setData('Text', target.id); 
  92.     } 
  93.          
  94.      
  95.     for (var i = 0; i < items.length; i++) { 
  96.         var item = items[i]; 
  97.         item.setAttribute("draggable", "true"); 
  98.         addEvent(item, 'dragstart', onDrag); 
  99.     }; 
  100. }); 

本文的demo可以在http://developerdrive.developerdrive.netdna-cdn.com/wp-content/uploads/2013/09/cart.html中看到,

完整代碼可以在http://developerdrive.developerdrive.netdna-cdn.com/wp-content/uploads/2013/09/cart.zip中獲得下載。

 

責(zé)任編輯:陳四芳 來源: 51CTO
相關(guān)推薦

2017-12-25 11:50:57

LinuxArch Linux

2018-06-11 15:30:12

2017-01-19 21:08:33

iOS路由構(gòu)建

2019-03-05 14:09:27

Docker存儲容器

2019-07-09 15:23:22

Docker存儲驅(qū)動

2010-08-10 11:31:36

路由器配置NAT

2009-04-15 09:29:07

2018-12-24 10:04:06

Docker存儲驅(qū)動

2009-12-18 16:35:56

如何查找局域網(wǎng)發(fā)生的故

2010-08-12 10:02:16

路由器NAT

2009-08-14 11:35:01

Scala Actor

2010-03-04 16:28:17

Android核心代碼

2018-03-07 15:24:41

PythonMySQL

2010-04-07 13:05:57

2024-11-18 17:12:18

C#編程.NET

2018-07-13 15:36:52

2017-01-06 15:13:25

LinuxVim源代碼

2019-04-01 10:15:02

2015-07-27 16:06:16

VMware Thin虛擬化

2016-11-02 18:54:01

javascript
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號