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

在豐林等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè) 網(wǎng)站設(shè)計(jì)制作按需求定制制作,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計(jì),成都全網(wǎng)營(yíng)銷,外貿(mào)網(wǎng)站建設(shè),豐林網(wǎng)站建設(shè)費(fèi)用合理。
開始
首先我們需要設(shè)計(jì)購(gòu)物車的基礎(chǔ)結(jié)構(gòu)和準(zhǔn)備一系列的商品。為了簡(jiǎn)單演示使用了各類商品,這里只是使用HTML 5中的data_*屬性(可參考https://developer.mozilla.org/en-US/docs/Web/Guide/HTML /Using_data_attributes),為各個(gè)商品添加了價(jià)格。簡(jiǎn)單來(lái)說(shuō),data_屬性是讓用戶可以為某些標(biāo)簽存儲(chǔ)一些額外的數(shù)據(jù)信息。代碼如下所示:
- 0.00
- Product 1
- Product 2
- Product 3
- Product 4
- Product 5
- Product 6
- Product 7
由于本文是主要講解使用Javascript搭配HTML 5的新功能,因此不會(huì)使用大家常用的jQuery。下面編寫addEvent事件,代碼如下:
- function addEvent(element, event, delegate ) {
- if (typeof (window.event) != 'undefined' && element.attachEvent)
- element.attachEvent('on' + event, delegate);
- else
- element.addEventListener(event, delegate, false);
- }
我們將使用的***個(gè)事件是readystatechange 。該事件在當(dāng)文檔的狀態(tài)發(fā)生改變的時(shí)候觸發(fā),我們期望將其狀態(tài)設(shè)置為“complete”,直到附加上剩余的事件和邏輯代碼。這個(gè)跟jQuery中的.ready事件類似。代碼如下:
- addEvent(document, 'readystatechange', function() {
- if ( document.readyState !== "complete" )
- return true;
- });
對(duì)DOM查詢
在HTML 5標(biāo)準(zhǔn)中,DOM的選擇器方面也進(jìn)行了更新,其中新增的功能中最有用的方法就是querySelectorAll。這個(gè)方法允許用戶使用更復(fù)雜的css樣式選擇器(有點(diǎn)象jQuery)去查詢頁(yè)面元素。這比舊有的通過(guò)class和ID去進(jìn)行查詢簡(jiǎn)單些。
下面是其中一個(gè)例子:
- var items = document.querySelectorAll("section.products ul li");
- var cart = document.querySelectorAll("#cart ul")[0];
這里,首先是分別使用items和cart變量獲得商品列表和購(gòu)物車列表,留作稍候使用??梢钥吹剑厦嫱ㄟ^(guò)querySelectorAll的方 法比以往更加方便了。既然已經(jīng)有了產(chǎn)品的列表,那么我們將實(shí)現(xiàn)拖拽功能并且當(dāng)產(chǎn)品被拖拽的時(shí)候,必須要有相關(guān)的事件進(jìn)行監(jiān)聽。為了實(shí)現(xiàn)這個(gè)目的,將循環(huán)遍 歷商品列表并且使用setAttribute方法設(shè)置draggable屬性為true,這里并且要為每個(gè)商品都添加dragstart事件。代碼如下:
- for (var i = 0; i < items.length; i++) {
- var item = items[i];
- item.setAttribute("draggable", "true");
- addEvent(item, 'dragstart', onDrag);
- };
在上面的代碼中,請(qǐng)注意將dragstart方法委托定義為onDrag。這個(gè)方法的目的是設(shè)置拖拽的選項(xiàng)并且保存元素的id留作稍候通過(guò)使用 dataTransfer.setData方法獲得數(shù)據(jù)。dataTransfer事件對(duì)象允許我們指定默認(rèn)的拖拽動(dòng)作的效果。默認(rèn)是既復(fù)制并移動(dòng),但這 里我們強(qiáng)制令其為只移動(dòng)元素。代碼如下:
- function onDrag(event){
- event.dataTransfer.effectAllowed = "move";
- event.dataTransfer.dropEffect = "move";
- var target = event.target || event.srcElement;
- var success = event.dataTransfer.setData('Text', target.id);
- }
#p#
設(shè)計(jì)購(gòu)物車
我們先來(lái)看下設(shè)計(jì)的購(gòu)物車大概是什么樣子的,如下圖:
看上去樣子不大漂亮,但這個(gè)并不影響我們的示例教學(xué)用??梢钥吹接脩艨梢酝侠赑roduct List中的商品到上面的購(gòu)物車區(qū)域中。
默認(rèn)元素是不接收drop事件的,因此為了能讓某個(gè)元素能接收到拖拽的事件消息,我們要重寫默認(rèn)的行為。為了實(shí)現(xiàn)這個(gè)目的,使用了onDragOver方法。代碼如下,所做的其實(shí)是阻止默認(rèn)的dragover和dragenter事件行為:
- function onDragOver(event){
- if(event.preventDefault) event.preventDefault();
- if (event.stopPropagation) event.stopPropagation();
- else event.cancelBubble = true;
- return false;
- }
- addEvent(cart, 'dragover', onDragOver);
接下來(lái),我們要往購(gòu)物車中增加商品了。只需要使用dataTransfer.getData方法從dataTransfer對(duì)象中取出id的值,有了id的值就可以從商品列表中找到商品。但要注意的是在往購(gòu)物車中放商品前要檢查該商品是否已經(jīng)放置在里面了,
檢查的方法很簡(jiǎn)單,只需要使用querySelectorAll方法就可以了,代碼如下:
- var exists = document.querySelectorAll("#cart ul li[data-id='" + id + "']");
接下來(lái)就很容易根據(jù)變量exists去判斷是否購(gòu)物車中已經(jīng)存在商品,代碼如下:
- if(exists.length > 0){
- updateCartItem(exists[0]);
- } else {
- addCartItem(item, id);
- }
在上面的代碼中,如果購(gòu)物車中不包含任何商品,則調(diào)用下面的代碼addCartItem。
- function addCartItem(item, id) {
- var clone = item.cloneNode(true);
- clone.setAttribute('data-id', id);
- clone.setAttribute('data-quantity', 1);
- clone.removeAttribute('id');
- var fragment = document.createElement('span');
- fragment.setAttribute('class', 'quantity');
- fragment.innerHTML = ' x 1';
- clone.appendChild(fragment);
- fragment = document.createElement('span');
- fragment.setAttribute('class', 'sub-total');
- clone.appendChild(fragment);
- cart.appendChild(clone);
- }
如果購(gòu)物車中不包含某件商品,則addCartItem方法中要做的事是克隆當(dāng)前的商品項(xiàng)?,F(xiàn)在可以指定的data-*的值。首先在克隆后的結(jié)點(diǎn)中,設(shè)置的是data-id結(jié)點(diǎn),然后設(shè)置data-quantity屬性為1并移除id屬性(id屬性在頁(yè)面中是唯一的)。然后我們?cè)黾觾蓚€(gè)新的span到列表項(xiàng)中,這是用來(lái)顯示小計(jì)項(xiàng)和產(chǎn)品的數(shù)量的。下圖是從商品列表中拖拉到購(gòu)物車中的情景:
更新購(gòu)物車中的商品
如果一個(gè)商品已經(jīng)在購(gòu)物車中存在了,我們將要增加其數(shù)量,其中我們顯示給用戶的方式是單價(jià)*數(shù)量,因此,我們使用 getAttribute方法就可以獲得當(dāng)前的數(shù)量并且對(duì)其進(jìn)行增加的操作,代碼如下:
- function updateCartItem(item){
- var quantity = item.getAttribute('data-quantity');
- quantity = parseInt(quantity) + 1
- item.setAttribute('data-quantity', quantity);
- var span = item.querySelectorAll('span.quantity');
- span[0].innerHTML = ' x ' + quantity;
- }
#p#
更新總價(jià)格
一旦購(gòu)物車的商品數(shù)量增加了,我們就要重新計(jì)算總價(jià)格。這里我們?cè)俅问褂昧?/p>
querySelectorAll功能。我們只需要遍歷購(gòu)物車中的每一個(gè)商品并重新計(jì)算價(jià)格就可以了,這里是取了兩位小數(shù)位。
- function updateCart(){
- var total = 0.0;
- var cart_items = document.querySelectorAll("#cart ul li")
- for (var i = 0; i < cart_items.length; i++) {
- var cart_item = cart_items[i];
- var quantity = cart_item.getAttribute('data-quantity');
- var price = cart_item.getAttribute('data-price');
- var sub_total = parseFloat(quantity * parseFloat(price));
- cart_item.querySelectorAll("span.sub-total")[0].innerHTML = " = " + sub_total.toFixed(2);
- total += sub_total;
- }
- document.querySelectorAll("#cart span.total")[0].innerHTML = total.toFixed(2);
從下圖中可以看到當(dāng)拖拽多個(gè)商品到購(gòu)物車中,商品的總價(jià)格是會(huì)增加的:
***我們總體看下所有的Javascript代碼如下所示。
- function addEvent(element, event, delegate ) {
- if (typeof (window.event) != 'undefined')
- element.attachEvent('on' + event, delegate);
- else
- element.addEventListener(event, delegate, false);
- }
- addEvent(document, 'readystatechange', function() {
- if ( document.readyState !== "complete" )
- return true;
- var items = document.querySelectorAll("section.products ul li");
- var cart = document.querySelectorAll("#cart ul")[0];
- function updateCart(){
- var total = 0.0;
- var cart_items = document.querySelectorAll("#cart ul li")
- for (var i = 0; i < cart_items.length; i++) {
- var cart_item = cart_items[i];
- var quantity = cart_item.getAttribute('data-quantity');
- var price = cart_item.getAttribute('data-price');
- var sub_total = parseFloat(quantity * parseFloat(price));
- cart_item.querySelectorAll("span.sub-total")[0].innerHTML = " = " + sub_total.toFixed(2);
- total += sub_total;
- }
- document.querySelectorAll("#cart span.total")[0].innerHTML = total.toFixed(2);
- }
- function addCartItem(item, id) {
- var clone = item.cloneNode(true);
- clone.setAttribute('data-id', id);
- clone.setAttribute('data-quantity', 1);
- clone.removeAttribute('id');
- var fragment = document.createElement('span');
- fragment.setAttribute('class', 'quantity');
- fragment.innerHTML = ' x 1';
- clone.appendChild(fragment);
- fragment = document.createElement('span');
- fragment.setAttribute('class', 'sub-total');
- clone.appendChild(fragment);
- cart.appendChild(clone);
- }
- function updateCartItem(item){
- var quantity = item.getAttribute('data-quantity');
- quantity = parseInt(quantity) + 1
- item.setAttribute('data-quantity', quantity);
- var span = item.querySelectorAll('span.quantity');
- span[0].innerHTML = ' x ' + quantity;
- }
- function onDrop(event){
- if(event.preventDefault) event.preventDefault();
- if (event.stopPropagation) event.stopPropagation();
- else event.cancelBubble = true;
- var id = event.dataTransfer.getData("Text");
- var item = document.getElementById(id);
- var exists = document.querySelectorAll("#cart ul li[data-id='" + id + "']");
- if(exists.length > 0){
- updateCartItem(exists[0]);
- } else {
- addCartItem(item, id);
- }
- updateCart();
- return false;
- }
- function onDragOver(event){
- if(event.preventDefault) event.preventDefault();
- if (event.stopPropagation) event.stopPropagation();
- else event.cancelBubble = true;
- return false;
- }
- addEvent(cart, 'drop', onDrop);
- addEvent(cart, 'dragover', onDragOver);
- function onDrag(event){
- event.dataTransfer.effectAllowed = "move";
- event.dataTransfer.dropEffect = "move";
- var target = event.target || event.srcElement;
- var success = event.dataTransfer.setData('Text', target.id);
- }
- for (var i = 0; i < items.length; i++) {
- var item = items[i];
- item.setAttribute("draggable", "true");
- addEvent(item, 'dragstart', onDrag);
- };
- });
本文的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中獲得下載。
新聞標(biāo)題:一步步教你如何用HTML 5拖拽功能打造購(gòu)物車
文章源于:http://m.5511xx.com/article/dphsgjg.html


咨詢
建站咨詢
