En av de nya funktionerna i HTML5 är inbyggd dra och släpp. Överraskande har Internet Explorer fått stöd för inbyggd dra och släpp sedan version 5.5; I själva verket bygger HTML5-implementeringen på IE: s stöd. I dagens handledning ser vi på hur man implementerar inbyggd dra och släpp för att skapa ett enkelt kundvagns gränssnitt.
Det här är vad vi ska bygga: det är en grundläggande kundvagn med en produktpanel och en kundvagn. För att "köpa" en produkt kan du dra den från panelen till vagnen. Vi håller koll på kvantitet och tar bort objekt från produktpanelen när de är slut i lager.
Observera att vi faktiskt inte bygger en kundvagn här. vi kommer inte att arbeta med någon server-sida godhet idag. Detta är bara fronten; poängen är att HTML5 dra och släppa.
Självklart börjar vi med HTML; här är vårt skal:
Dra och släpp kundvagn
Ganska grundläggande: vi länkar till ett stylesheet och jQuery; vi använder bara jQuery för enkel händelsehantering och DOM-manipulation; Drag och släpp kommer att vara infödd. Men vi står inför en vägg här, eftersom HTML5 dra och släppa lägger till några egenskaper till händelseobjektet. JQuery använder inte standardhändelseobjektet; det skapar en egen för att utjämna händelseobjektproblem. På grund av detta får vi inte de speciella egenskaperna med jQuerys händelseobjekt. Men oroa dig inte; det finns ett plugin för det; Vi drar in det Native Drag och Drop för att få allt att fungera. Slutligen kommer vi att inkludera vårt skript: dragdrop.js
.
Nu är vi redo att lägga till i vår produktlista; För produktbilder använder jag ikoner från Apple Icon Superpack, skapad av SvenVath. (Jag har bytt namn på ikonerna med enklare namn och ändrat dem till 180px.)
Lägg till ul # produkter
som första barnet inne i kroppen. När du har gjort det undersöker vi det första listobjektet:
iMac
Pris: $ 1199,00
Kvantitet: 10
Vi har ut listobjekt, med ett ankare inuti; märker att varje ankareobjekt kommer att ha en klass av Artikel
(viktigt när vi kommer till CSS) och ett anpassat ID (viktigt när vi kommer till JavaScript). Då har ankaren också dragbar = "true"
attribut; Detta borde vara allt vi behöver för att göra elementet draggbart (vi kommer snart att se några försummelser). Vi använder en ankare tagg så att du kan göra något för webbläsare utan inbyggt dra och släpp support (även om vi inte gör det här). Då har vi produktbilden och en div med produktinformationen. Och ja, det är nödvändigt att paketera priset och kvantiteten med spänna
Här är resten av listobjekten:
iPhone
Pris: $ 199.00
Kvantitet: 16
AppleTV
Pris: $ 299.00
Kvantitet: 9
Cinema Display
Pris: $ 899,00
Kvantitet: 4
iPod Nano
Pris: $ 149.00
Kvantitet: 20
Macbook
Pris: $ 1199,00
Kvantitet: 13
Mac Mini
Pris: $ 599,00
Kvantitet: 18
Det finns en sista bit av HTML: kundvagnen:
Kundvagn
Total: $0,00
Släpp här för att lägga till i kundvagnen
Och det är vår HTML!
Helst bör allt du behöver göra för att göra ett element som kan släppas, vilket sugbart attribut till sant; det finns dock mer. För att få saker att fungera korrekt måste du ställa in några saker i CSS. Tänk först på det här: Vad gör klick och släpning på "normalt" (undraggable) element? Vanligtvis väljer den text. Då vill vi se till att vi drar elementet och inte bara dess innehåll. För att hantera, måste du använda följande CSS:
[draggable = true] -moz-user-select: none; -webkit-användar-välj: ingen; -webkit-användare-dra: element;
För vår bekvämlighet sätter de inbyggda dra och släpp-plugin som vi använder dessa egenskaper för oss, så vi kan lämna dem om vi vill. Vi kommer dock att göra det här:
[draggable = true] markör: flytta;
Låt oss börja styling:
html höjd: 100%; kropp bakgrund: #ececec; marginal: 0; padding: 0; typsnitt: 13px / 1.5 helvetica, arial, san-serif; höjd: 100%; h1, h2 text-align: center; h2 position: absolut; botten: 20px; färg: #fff; textskugga: 0 0 10px rgba (0, 0, 0, 0,75); display: none; p marginal: 0;
Eftersom vi inte använder en fullständig återställning, här är vår pseudo-återställning. Det borde vara ganska självförklarande. Vi ställer höjden till 100% på html
och kropp
element eftersom vi vill #vagn
att vara hela skärmens höjd; för att göra det måste varje moderelement ha sin höjd inställd på 100%. Observera också att vi använder rgba för att ställa in skuggfärgen; Om en webbläsare inte stöder detta kommer det inte att finnas någon skugga på h2
. Och vi gömmer det här h2
genom att sätta display: none
. Kom ihåg att h2
säger "Släpp här för att lägga till i kundvagnen" så vi kommer att få det att blekna när draget börjar och blekna ut när draget slutar.
Fortsätt till vår produktlista ...
#products float: left; list-style: none; bredd: 65%; padding: 0; #products li display: inline;
Återigen, ganska uppenbart. Det viktiga i det här utdraget är att listobjekten kommer att visas inline. Eftersom vi ska ställa in display: block; flyta till vänster
På ankarna kommer IE att ge listposterna en "trappsteg" -effekt; Vi kan arbeta runt den här felet genom att ställa in display: inline
på ankarets grundelement.
Tala om ankarna, låt oss stile dem nästa.
.objekt display: block; flyta till vänster; bredd: 180px; höjd: 180px; margin: 10px; gräns: 1px fast # 494949; text-align: center; text-decoration: none; färg: # 000; overflow: hidden; .item img border: 0; marginal: 10px auto; bredd: 160px; höjd: 160px; .item div bakgrund: rgb (0, 0, 0); bakgrund: rgba (0, 0, 0, 0,5); positioner: relativ; botten: 69px; color: # f3f3f3; vaddering: 5px 0; display: none;
Varje ankare ska formas som en 180x180px låda; Detta kommer att fyllas med produktbilden. Produktinfo div kommer att placeras över bilden, längst ner på torget. Observera att vi måste ange en bakgrundsfärg och sedan återställa den till moderna webbläsare, eftersom IE inte stöder RGBa. Vi ställer in display: none
på denna info div så vi kan blekna det in och ut när "kunden" svänger på respektive av.
Allt som är kvar att stilen är kundvagnen. vi tittar på det här, men kom ihåg att listobjekten kommer att införas av jQuery senare, så du ser inte detta på plats ännu.
#cart float: right; bakgrundsfärg: #ccc; bredd: 25%; vaddering: 0 5%; höjd: 100%; #cart ul vaddering: 0; #cart li list-style: none; gränsbotten: 1px fast # 494949; padding: 5px; #cart .quantity font-weight: bold; padding-right: 10px; margin-höger: 10px; gräns-höger: 1px fast # 494949; display: inline-block; bredd: 15px; text-align: right; #cart .price float: right; #total float: right;
Elements med klasserna kvantitet
och pris
kommer att ligga inom de dynamiskt infogade listobjekten.
Det är det för CSS; Innan vi går vidare till stjärnan i denna show, låt oss titta på vårt arbete hittills.
Vi har gjort det till JavaScript; enligt HTML5-doktorn:
HTML 5 DnD bygger på Microsofts ursprungliga implementering som var tillgänglig så tidigt som Internet Explorer 5! Nu stöds för närvarande i IE, Firefox 3.5 och Safari 4.
Här är en lista över händelser som HTML5 dra och släpper erbjudanden:
Vi kommer inte använda alla dessa, men vi får se hur de flesta arbetar.
Först ska vi arbeta med våra produkter:
$ ('. item') .bind ('dragstart', funktion (evt) evt.dataTransfer.setData ('text', this.id); $ ('h2'). fadeIn ('fast');) .hover (funktion () $ ('div', detta) .fadeIn ();, funktion () $ ('div', detta) .fadeOut (););
Vi börjar med att ta alla saker; då binder vi en funciton till dragstart
händelse; den här händelsen kommer att skjuta när vi börjar dra händelsen. Det första vi gör när ett föremål släpas sätter vissa data. faktiskt, om ingen data är inställd, kommer Firefox inte att låta elementet dra. Särskilda att dra händelser är en objektegenskap på det händelseobjekt som heter dataöverföring
; vi använder två metoder för den här egenskapen: setData
och hämta data
. Här använder vi setData
metod, som tar två parametrar: ett dataformat och data. Vi använder datatypen 'text'. Då ställer vi in data som id av det element som användaren drar. Då vi bleknar i h2
som en snabb till kunden.
Vi använder också jQuery-svängmetoden för att blekna i produktinformationen när vi muspekar och tona ut det när vi mouseout. Observera att vi passerar noden som vi svävar över som kontext, så vi får bara div av lämplig produkt.
Låt oss nu lägga till händelsehanterare till #vagn
. Vi ska agera på Dra över
, dragenter
, och släppa
evenemang:
$ ('# cart') .bind ('dragover', funktion (evt) evt.preventDefault ();) .bind ("dragare", funktion (evt) evt.preventDefault ();) .bind "drop", funktion (evt) );
För att få dropphändelsen att skjuta måste vi avbryta standardåtgärden på Dra över
händelse; Denna händelse brinner kontinuerligt på drop-målet när ett dragbart element släpas över det. För endast IE måste vi avbryta standardåtgärden på dragenter
händelse, som bara uppträder när det dragbara elementet går in i drop-målet. Anledningarna till att avbryta standardåtgärden är något dimmiga; För att vara ärlig förstår jag inte dem. Här är vad Remy Sharp säger om det:
Vad det säger till webbläsaren är att det här elementet är det vi vill få dra händelsen mot, annars går webbläsaren framåt, det är normalt dragåtgärd. Så genom att avbryta händelsen berättar den till webbläsaren att detta är det element som ska börja röra sig.
Jag bör notera att jQuery hjälper oss lite här, normalt skulle vi också behöva returnera falskt
det får det att fungera i IE; dock är jQuery fast prevent
gör det för oss.
Nu den släppa
händelse; Denna händelse är också avfyrade på drop-målet, vilket är div # varukorg
i vårat fall. Innan vi tittar på funktionen, låt oss prata om vad den här funktionen ska göra:
Här är den första delen:
var id = evt.dataTransfer.getData ('text'), objekt = $ ('#' + id), cartList = $ ("# cart ul"), totalt = $ ("# total span"), pris = $ ('p: eq (1) span', objekt) .text (), prevCartItem = null, inteInCart = (funktion () var lis = $ ('li', kartlista), len = lis.length, i; (i = 0; i < len; i++ ) var temp = $(lis[i]); if (temp.data("id") === id) prevCartItem = temp; return false; return true; ()), quantLeftEl, quantBoughtEl, quantLeft;
Jag vet; Det är många variabler, men vi använder dem alla. Låt oss gå över dem; Först får vi de textdata som vi överförde med evenemanget. Vi överförde idet så här eftersom det inte finns något i händelseobjektet för att berätta vilket element som släpptes på vårt mål. vi får idet och använder sedan det för att hitta elementet som släpptes. Därefter får vi kundvagnslistan och den totala prisklassen. Då får vi priset på det enskilda objektet. Vi vet att det är spetsen inom punktens andra stycke, så vi kan använda objektet som kontextparameter. Vi ställer in prevCartItem
till null för nu, men vi använder den för att se om föremålet släpade in i vagnen finns redan där. Värdet av notInCart
är en självkrävande anonym funktion det kommer att slingra över varje listobjekt i kartlistan (igen, vi använder kontextparametern) och kontrollera om dataegenskapen id
är samma som variabeln id
. För att förstå detta måste du veta att när vi lägger till listobjekt i kundvagnen använder vi jQuery data
Metod för att ställa in affärs-id med objektet. I denna funktion söker vi efter ett listobjekt med rätt data; om vi hittar en, är föremålet redan i kundvagnen, och så ställer vi in notInCart
till falskt; Om den inte finns i vagnen ställer vi variabeln till sant. Slutligen använder vi quantLeftEl
, quantBoughtEl
, och quantLeft
vid uppdatering av kvantiteter.
Nu, för några åtgärder:
$ ( "H2") fadeout ( 'snabb'). om (inteInCart) prevCartItem = $ ('', text: $ (' p: first ', item) .text (), data: id: id)', ' class ':' kvantitet ', text:' 0 ')) prepend ($ ('', ' class ':' pris ', text: pris)) appendTo (cartList);
Först kommer vi att blekna ut h2
prompt. Sedan, om objektet inte finns i kundvagnen lägger vi till det i vagnen. För att göra detta ska vi skapa ett listobjekt; då kan vi passera ett objekt bokstavligt som den andra parametern för att ställa in egenskaper för vårt nya listobjekt. Vi ställer in texten till produktnamnet. som kommer från första stycket i produktartikeln. Sedan satte vi upp de data vi pratade om ovan.
Därefter lägger vi ett spannmål till det här listobjektet. vi ska ge den en klass av "kvantitet" (glöm inte att sätta klass i citat, eftersom det är ett reserverat ord) och ställa texten till noll; Ja, jag vet att det borde vara en, eftersom de bara har lagt föremålet i vagnen, men vi ökar det senare ... och du kommer att se varför.
Vi lägger ut ett annat spannmål till listobjektet, den här gången till priset. Vi ska flyta priset till höger, så det verkar logiskt att bifoga Det; men det skulle orsaka en float bug i IE; spänningen skulle actaully flyta rätt och under listobjektet.
Slutligen lägger vi till listobjektet i kundvagnen.
Den sista delen av den här funktionen kommer att köras om objektet redan finns i kundvagnen eller ej:
quantLeftEl = $ ('p: sista span', objekt); quantLeft = parseInt (quantLeftEl.text (), 10) - 1; quantLeftEl.text (quantLeft); quantBoughtEl = $ ('. kvantitet', prevCartItem); quantBoughtEl.text (parseInt (quantBoughtEl.text (), 10) + 1); om (quantLeft === 0) item.fadeOut ('fast'). ta bort (); total.text ((parseFloat (total.text (), 10) + parseFloat (price.split ('$') [1]). toFixed (2)); evt.stopPropagation (); returnera false;
Först får vi kvantiteten från produkten. Det här är den mängd som kvarstår när kunden slog varan till vagnen. vi får då den mängd som verkligen är kvar; men det är en sträng, så vi använder den inbyggda funktionen parseInt
att konvertera det till ett tal (använd 10 som radix för att försäkra att vi får ett decimaltal) och subtrahera ett från det. Sedan återställer vi kvantiteten med jQuery's text
metod.
Därefter får vi den mängd som användaren har köpt; Detta är elementet med en klass av "kvantitet"; vi använder prevCartItem
som sammanhanget Detta fungerar för att om varan redan fanns i vagnen, prevCartItem
sattes i den anonyma funktionen; om det inte fanns i vagnen, satte vi det när vi skapade kundvagnen. Vi kan sedan ställa in textvärdet genom att få det aktuella värdet, konvertera till ett nummer och lägga till ett till det.
Vad händer när mängden kvarstår noll? Om det är noll, tappar vi ut objektet och tar bort det.
Slutligen måste vi uppdatera det totala priset. Vi har den totala spänningen, så vi kan bara återställa texten. vad vi gör är att få den nuvarande texten, konvertera den till ett nummer (den här gången använder vi parseFloat
för att hålla centen), splittra dollarn tecknet av priset och konvertera det till ett tal och lägga till två värden. Slutligen använder vi toFixed
för att se till att vi alltid visar rätt cents värde.
Slutligen vill vi inte ha släppa
släpp händelse till bubbla, så vi kommer att stoppa dess fortplantning och återvända falskt;
Bra jobb, vi är färdiga här är ett skott av vår kundvagn i aktion:
Om du vill kolla vad de andra dra och släpp händelserna gör, lägg till det här till skriptet:
$ ('# cart'). bind ('draga', funktion (evt) console.log ('dragleave');); $ ('. item') .bind ('drag', funktion (evt) console.log ('dragend');) .bind ('dragstart', funktion (evt) console.log ('dragstart') ;) .bind ("dra", funktion (evt) console.log ("dra"););
Medan inbyggd HTML5 dra och släpp kanske inte är helt klar för prime time just (Opera stöder det inte) är det definitivt spännande att se var saker går!