Allmänna frågor och teori om Dra och släpp-teknik. Dra och släpp-teknik i Android Se vad "Drag-och-släpp" är i andra ordböcker

182

I det här exemplet väljer vi ett div-element och gör det rörligt genom att anropa metoden draggable() på det. Som visas i figuren nedan tar elementet sin vanliga position i det öppnade dokumentet, men efter det kan det flyttas med muspekaren till valfri plats i webbläsarfönstret:

Möjligheten att dra och släppa element är användbar i sig, men den är ännu mer användbar när den används tillsammans med den släppbara interaktionen, som beskrivs härnäst.

Dragbar interaktion uppnås enbart genom användning av specifika HTML-uppmärkningar och CSS-stilar. Detta betyder att den här funktionen kommer att fungera i nästan alla webbläsare, men de element som är utrustade med den kommer inte att kunna fungera med liknande inbyggda dra-och-släpp-verktyg operativsystem.

Dra-och-släpp-operationer som definieras av HTML5-specifikationen implementeras vanligtvis med inbyggda operativsystemmekanismer. Om du använder dra-och-släpp-mekanismen i jQuery UI är det bättre att inaktivera motsvarande HTML5-funktioner för att undvika konflikter. För att göra detta, ställ in det dragbara attributet för dokumentelementet till false.

Konfigurera den dragbara interaktionen

Det finns många anpassningsalternativ för dragbara interaktioner. De viktigaste egenskaperna, som diskuteras i följande avsnitt, visas i tabellen nedan:

Dragbara interaktionsegenskaper egendomsbeskrivning
axel Begränsar möjligheten att röra sig i vissa riktningar. Standardvärdet är falskt, vilket betyder att det inte finns några begränsningar, men du kan också ange ett värde på "x" (flytta endast längs X-axeln) eller "y" (flytta endast längs Y-axeln)
inneslutning Begränsar platsen för elementet som flyttas till ett specifikt område på skärmen. Typerna av värden som stöds beskrivs i tabellen nedan, med hjälp av motsvarande exempel. Standardvärdet är falskt, vilket betyder inga begränsningar
dröjsmål Anger hur länge ett element måste dras innan det flyttas. Standardvärdet är 0, vilket betyder ingen fördröjning
distans Definierar avståndet som användaren måste dra ett element från dess startposition innan det faktiskt rör sig. Standardvärdet är 1 pixel
rutnät Tvingar snäppningen av det flyttade elementet till rutnätscellerna. Standardvärdet är false, vilket betyder ingen bindning
Begränsande rörelseriktningar

Det finns flera sätt du kan begränsa ett elements rörelse till vissa riktningar. Det första är att använda axelalternativet, som låter dig begränsa rörelseriktningen till X- eller Y-axeln. Ett exempel på detta visas nedan:

... div.dragElement (font-size: large; border: small solid black; padding:16px; width: 8em; text-align: center; background-color: lightgrey; margin: 4px ) $(function() ( $ (".dragElement").draggable((axel: "x")).filter("#dragV").draggable("alternativ", "axel", "y"); )); Dra vertikalt Dra horisontellt Kör exempel

I det här exemplet definierar vi två div-element, väljer dem med jQuery och anropar metoden draggable(). Som ett argument för denna metod skickar vi ett objekt som initialt begränsar rörelsen av båda div-elementen till riktningen längs X-axeln. Genom att sedan använda metoden jQuery filter() kan vi välja dragV-elementet utan att jQuery söker i hela dokumentet igen och ställ in det i en annan tillåten rörelseriktning - längs Y-axeln. Således får vi ett dokument där ett div-element endast kan dras i vertikal riktning och det andra - endast i horisontell riktning. Resultatet visas i figuren:

Begränsning av det tillåtna området för elementrörelser

Du kan också begränsa området på skärmen där du kan dra ett objekt. För att göra detta, använd inneslutningsalternativet. Värdeformaten som kan anges i det här alternativet beskrivs i tabellen nedan:

Ett exempel på användning av inneslutningsalternativet ges nedan:

... div.dragElement (font-size: large; border: small solid black; padding:16px; width: 8em; text-align: center; background-color: lightgray; margin: 4px ) #container ( kantlinje: medium dubbel svart; bredd: 700px; höjd: 450px) $(function() ( $(".dragElement").draggable((inneslutning: "förälder" )).filter("#dragH").draggable("option", " axel", "x"); )); Dra horisontellt Dra inuti förälder Kör exempel

I det här exemplet är båda elementen begränsade i sin förmåga att röra sig så att de bara kan dras inom sitt överordnade element, som är en div med fast storlek. En av diverna som flyter har den ytterligare begränsningen att den flyter med hjälp av axelalternativet, eftersom den bara kan röra sig horisontellt inom sin överordnade. Resultatet illustreras i figuren:

Begränsar möjligheten att flytta ett element till rutnätsceller

Gridalternativet låter dig ställa in bindningen av det flyttade elementet till rutnätsceller. Det här alternativet tar som ett värde en matris med två element som anger bredden och höjden på rutnätscellerna i pixlar. Ett exempel på hur du använder rutnätsalternativet ges nedan:

... #draggable (font-size: x-large; border: small solid black; width: 5em; text-align: center; padding:10px) $(function() ( $("#draggable").draggable( ( rutnät: )); )); Drag me Run exempel

Det här exemplet anger ett rutnät med celler 100 pixlar breda och 50 pixlar höga. När du drar ett element "hoppar" det från en (osynlig) cell till en annan. Snäppeffekten är ett bra exempel på hur interaktionsfunktionalitet kan användas, men det är svårt att förmedla med skärmdumpar.

Du kan skapa en snapeffekt för endast en riktning genom att ställa in den fria rörelseaxeln till 1. Om du till exempel ställer in rutnätsalternativet till , kommer elementet att fästa till 100 pixlar breda rutnätsceller när det flyttas horisontellt, men kommer att röra sig fritt vertikalt.

Flyttfördröjning

Det finns två alternativ som låter dig fördröja dragningen av ett rörligt element. Fördröjningsalternativet låter dig ange hur lång tid, i millisekunder, som användaren måste dra muspekaren innan elementet faktiskt flyttas. En annan typ av fördröjning tillhandahålls av avståndsalternativet, som anger avståndet i pixlar som användaren måste dra muspekaren innan den följs av ett element.

Ett exempel på hur du använder båda inställningarna ges nedan:

... #tid, #avstånd (font-size: large; kant: tunn fast svart; stoppning: 10px; bredd: 120px; text-align: center; bakgrundsfärg: ljusgrå; marginal: 4px; ) $(function( ) ( $("#time").draggable(( delay: 1000 )) $("#distance").draggable(( avstånd: 150 )) )); Block med tidsfördröjning Block med minsta distans Löpexempel

I det här exemplet finns det två rörliga element, varav det ena är fördröjt med fördröjningsalternativet och det andra fördröjs med avståndsalternativet.

I fallet med en fördröjning, specificerad av fördröjningsalternativet, måste användaren dra en viss tid innan den faktiskt flyttar elementet. I det här exemplet är längden på denna period 1000 ms. Det är inte nödvändigt att flytta musen just nu, men under hela fördröjningsperioden måste musknappen förbli nedtryckt, varefter elementet kan flyttas genom att flytta musen. Efter att fördröjningstiden har löpt ut kommer elementet som flyttas att snäppa till muspekarens plats, med förbehåll för de begränsningar som ställs av rutnätet, regionen och axelalternativen som diskuterats tidigare.

Avståndsalternativet har en liknande effekt, men i det här fallet måste användaren dra muspekaren minst ett visst antal pixlar i valfri riktning från elementets startplats. Elementet som flyttas kommer då att hoppa till den aktuella pekarens plats.

Om du tillämpar båda inställningarna på samma element kommer det flyttade elementet inte att flyttas förrän båda fördröjningskriterierna är uppfyllda, d.v.s. tills ett försök att dra ett element varar under en viss tid och tills muspekaren flyttar ett visst antal pixlar.

Använda dragbara interaktionsmetoder

Alla metoder som definieras för dragbar interaktion är en del av uppsättningen basmetoder som du redan har sett när du tittar på widgets. Det finns inga metoder som är specifika för Draggable-interaktion, så vi kommer inte att täcka dem i detalj. Listan över tillgängliga metoder finns i tabellen nedan:

Använda dragbara interaktionshändelser

Interaktion Draggable stöder en enkel uppsättning händelser som meddelar dig när ett element dras. Dessa händelser beskrivs i tabellen nedan:

Precis som med widgethändelser kan dessa händelser också besvaras. Ett exempel på hantering av start- och stopphändelser ges nedan:

... #draggable (font-size: x-large; kant: tunn fast svart; bredd: 190px; text-align: center; padding:10px) $(function() ( $("#draggable").draggable( ( start: function() ( $("#draggable").text("Dra mig..."), stop: function() ( $("#draggable").text("Drag me") ) )) ;)); Drag me Run exempel

Det här exemplet använder start- och stopphändelser för att ändra textinnehållet i ett element när det dras. Denna fördel beror på det faktum att Draggables interaktion implementeras helt med HTML och CSS: du kan använda jQuery för att ändra tillståndet för ett dragbart element även när det rör sig över skärmen.

Använder släppbar interaktion

Att dra ett element enbart kan vara tillräckligt i vissa situationer, men det är mest användbart när det används tillsammans med den släppbara interaktionen.

Element som den släppbara interaktionen har tillämpats på (mottagande element) får förmågan att acceptera rörliga element som skapats med hjälp av den dragbara interaktionen.

Mottagande element skapas med metoden droppable(), men för att få användbar funktionalitet måste du skapa händelsehanterare bland de som definieras för denna typ av interaktion. Tillgängliga evenemang visas i tabellen nedan:

Släppbara interaktionshändelser Händelsebeskrivning
skapa Uppstår när en släppbar interaktion tillämpas på ett element
Aktivera Uppstår när användaren börjar dra elementet som flyttas
avaktivera Uppstår när användaren slutar dra elementet som flyttas
över Uppstår när användaren drar ett flytbart element över ett mottagande element (förutsatt att musknappen inte har släppts ännu)
ut Uppstår när användaren drar elementet som flyttas utanför det mottagande elementet
släppa Uppstår när användaren lämnar elementet som flyttas på det mottagande elementet

Ett exempel på att skapa ett enkelt mottagande element för vilket en enda släpphändelsehanterare är definierad ges nedan:

... #dragbar, #släppbar (font-size: large; kant: tunn fast svart; stoppning: 10px; bredd: 100px; text-align: center; bakgrundsfärg: ljusgrå; marginal: 4px;) #dropable (stoppning) : 20px; position: absolut; höger: 5px;) $(function() ( $("#draggable").draggable(); $("#doppable").dropable(( drop: function() ( $(" #draggable").text("Vänster") ) )); )); Lämna mig här Dra mig Kör exempel

Det här exemplet lägger till ett div-element i dokumentet vars textinnehåll representeras av strängen "Lämna här." Vi väljer det här elementet med jQuery och anropar metoden droppable() och skickar det ett inställningsobjekt som definierar en hanterare för drop-händelsen. Svaret på denna händelse är att ändra texten i elementet som flyttas med metoden text().

Dra-och-släpp-interaktionen som skapats i det här exemplet är enkel, men den ger en användbar kontext för att förklara hur de Drag-och-släpp-interaktioner fungerar tillsammans. De olika stegen i processen att dra element illustreras i figuren:

Det hela ser väldigt enkelt ut. Vi drar elementet som flyttas tills det är ovanför det mottagande elementet och släpper det. Elementet som släpps förblir där det lämnades, och dess textinnehåll ändras som svar på släpphändelsen. Följande avsnitt visar hur du använder andra släppbara interaktionshändelser för att förbättra användarupplevelsen.

Belysning av målmottagande objekt

Med hjälp av aktiverings- och avaktiveringshändelserna kan du markera målmottagningsobjektet när användaren börjar dra ett element. I många situationer är denna idé mycket fruktbar eftersom den ger användaren tillförlitlig vägledning om vilka element som ingår i dra-och-släpp-modellen. Ett motsvarande exempel ges nedan:

... $(function() ( $("#draggable").draggable(); $("#doppable").droppable(( drop: function() ( $("#draggable").text("Vänster ") ), aktivera: function() ( $("#dropable").css(( kantlinje: "medium dubbelgrön", bakgrundsfärg: "lightGreen" )); ), deaktivera: function() ( $("#doppable ").css("kant", "").css("bakgrundsfärg", ""); ) )); )); ...Kör exempel

Så snart användaren börjar dra ett element, aktiveras händelsen som är associerad med vårt mottagande element, och hanterarfunktionen använder metoden css() för att ändra gräns- och bakgrundsfärgens CSS-egenskaper för det elementet. Som ett resultat markeras det målmottagande elementet, vilket indikerar för användaren att det finns en koppling mellan det och elementet som flyttas.

Deaktiveringshändelsen används för att ta bort CSS-egenskapsvärden från det mottagande elementet och returnera det till initialtillståndet, så snart användaren släpper musknappen. (Denna händelse inträffar när dragningen av ett element upphör, oavsett om elementet som dras lämnas kvar på det mottagande elementet eller inte.) Denna process illustreras i figuren:

Hantera överlappande element

Dra-och-släpp-tekniken kan förbättras genom att lägga till över- och uthändningshantering. Överhändelsen inträffar när 50 % av elementet som flyttas är över någon del av det mottagande elementet. Uthändelsen inträffar när tidigare överlappande element inte längre överlappar varandra. Ett exempel på svaret på dessa händelser ges nedan:

$(function() ( $("#draggable").draggable(); $("#doppable").dropable(( drop: function() ( $("#draggable").text("Left") ) , aktivera: function() ( $("#dropable").css(( kantlinje: "medium dubbelgrön", bakgrundsfärg: "lightGreen" )); ), deaktivera: function() ( $("#doppable"). css("border", "").css("bakgrundsfärg", ""); ), över: function() ( $("#doppable").css(( kantlinje: "medium dubbel röd", bakgrundsfärg : "röd" )); ), ut: function() ( $("#doppable").css("kant", "").css("bakgrundsfärg", ""); ) )); ) ); Kör exempel

Samma hanterarfunktioner används här som i föregående exempel, men i det här fallet är de associerade med över- och uthändelserna. När det mottagande elementet överlappar minst 50 % av elementet som flyttas, är det inneslutet i en ram och dess bakgrundsfärg ändras, som visas i figuren:

Denna gräns på 50 % kallas överlappströskeln (tolerans), vars värde kan ställas in när du skapar det mottagande elementet, vilket kommer att visas senare.

Konfigurera släppbara interaktioner

Den släppbara interaktionen har ett antal egenskaper som du kan ändra för att anpassa dess beteende. Dessa egenskaper listas i tabellen nedan:

Släppbara interaktionsegenskaper egendomsbeskrivning
Inaktiverad Om det här alternativet är sant, är den släppbara interaktionsfunktionen initialt inaktiverad. Standardvärdet är falskt
acceptera Begränsar uppsättningen av rörliga element som det mottagande elementet kommer att svara på. Standardvärdet är *, vilket matchar alla element
activeClass Definierar en klass som kommer att tilldelas som svar på aktiveringshändelsen och tas bort som svar på avaktiveringshändelsen
hoverClass Definierar en klass som kommer att tilldelas som svar på en överhändelse och tas bort som svar på en uthändelse
tolerans Definierar den lägsta graden av överlappning vid vilken en överhändelse inträffar
Begränsning av tillåtna element som ska flyttas

Du kan begränsa uppsättningen av släppbara element som kommer att accepteras av ett element med släppbar interoperabilitetsfunktion genom att använda alternativet acceptera. Värdet för alternativet acceptera bör ställas in på en väljare. Som ett resultat kommer släppbara interaktionshändelser endast att inträffa om elementet som flyttas matchar den angivna väljaren. Ett motsvarande exempel ges nedan:

... .dragbar, #dropable (font-size: large; border: thin solid black; stoppning: 10px; bredd: 100px; text-align: center; bakgrundsfärg: ljusgrå; margin: 4px;) #dropable (stoppning) : 20px; position: absolut; höger: 5px;) $(function() ( $(".draggable").draggable(); $("#doppable").dropable(( drop: function(event, ui) ( ui.draggable.text("Vänster") ), activate: function() ( $("#doppable").css(( kantlinje: "medium dubbelgrön", bakgrundsfärg: "lightGreen" )); ), deaktivera: funktion () ( $("#droppable").css("kant", "").css("bakgrundsfärg", ""); ), acceptera: "#drag1" )); )); Lämna här Element 1 Element 2 Körexempel

I det här exemplet finns det två dragbara element med ID:n drag1 och drag2. När vi skapar ett mottagande element använder vi alternativet acceptera, med vilket vi indikerar att endast drag1-elementet kommer att vara ett acceptabelt element som ska flyttas.

När du drar elementet drag1 kommer du att se samma effekt som i de tidigare exemplen. Vid lämpliga tidpunkter kommer aktiverings-, avaktiverings-, över- och uthändelserna att aktiveras för det mottagande elementet. Samtidigt, om du drar ett drag2-element som inte matchar väljaren som anges i acceptparametern, kommer dessa händelser inte att aktiveras. Detta element kan flyttas fritt, men det kommer inte att uppfattas av det mottagande elementet.

Lägg märke till förändringen i hur vi väljer ett acceptabelt flytbart element för att anropa text()-metoden. När det bara fanns ett rörligt element i dokumentet räckte id-attributet för detta:

Släpp: function() ( $("#draggable").text("Left") ),

I det här exemplet finns det två flytbara element, och att välja efter id-attribut ger inte det önskade resultatet, eftersom texten i detta fall alltid kommer att ändras i samma flytbara element, oavsett vilket som är acceptabelt för det mottagande elementet.

Lösningen är att använda UI-objektet, som jQuery UI tillhandahåller som ett extra argument till varje händelsehanterare. Den dragbara egenskapen för ett ui-objekt returnerar ett jQuery-objekt som innehåller elementet som användaren drar eller försöker släppa på målelementet, vilket gör att det önskade elementet kan väljas så här:

Släpp: function(event, ui) ( ui.draggable.text("Left") ),

Ändra överlappningströskeln

Som standard inträffar överhändelsen endast när minst 50 % av elementet som flyttas överlappar det mottagande elementet. Mängden av denna tröskelöverlappning kan ändras med hjälp av toleransalternativet, som kan ta de värden som visas i tabellen nedan:

De två värdena jag använder oftast är passform och beröring eftersom de är mest meningsfulla för användarna. Jag använder passform när det släpade elementet behöver förbli i området för det mottagande elementet det flyttades till, och pekar när det släpade elementet behöver återgå till sin ursprungliga position (ett exempel kommer att ges nedan). Ett exempel på användning av passnings- och beröringsparametrarna ges nedan:

Klonvärdet talar om för jQuery UI att skapa en kopia av elementet som flyttas, tillsammans med allt dess innehåll, och använda det resulterande resultatet som ett hjälpelement. Resultatet visas i figuren:

Hjälpelementet tas bort när användaren släpper musknappen över elementet som flyttas, vilket lämnar elementet som flyttas och det mottagande elementet i sina ursprungliga positioner.

Som visas i figuren förblir det ursprungliga elementet som flyttas på plats och endast hjälpelementet rör sig runt skärmen efter muspekaren. Om storleken på det flyttade elementet är stort, som i vårt exempel, täcker det resten av dokumentelementen, så att det blir svårt för användaren att ens spåra positionen för det mottagande elementet. Det här problemet kan lösas genom att tillhandahålla funktionen som värdet för hjälpalternativet, som visas i exemplet nedan:

... $(function() ( $("div.draggable")..png"/>") ) )); $("#basket").dropable((activeClass: "active", hoverClass: "hover" )); )); ...Kör exempel

När användaren börjar dra ett element anropar jQuery UI funktionen som specificeras av helper-parametern och använder det returnerade elementet som objektet som ska dras. I det här fallet använder jag jQuery för att skapa img-elementet. Resultatet visas i figuren:

En liten bild fungerar som en proxy för elementet som flyttas, vilket gör det mycket lättare att hålla reda på andra element i dokumentet.

Ui-objektet som jQuery UI skickar till släppbara interaktionshändelser innehåller en hjälpegenskap, och den här egenskapen kan användas för att manipulera hjälparen när den dras. Ett exempel på hur den här egenskapen används i samband med över- och sluthändelserna ges nedan:

... $(function() ( $("div.draggable")..png"/>") ) )); $("#basket").doppable(( activeClass: "active", hoverClass: "hover", over: function(event, ui) ( ui.helper.css("border", "thick solid #27e6ed") ) , ut: function(event, ui) ( ui.helper.css("border", "") ) )); )); ...

Här används över- och uthändelserna och egenskapen ui.helper för att visa en ram runt hjälparelementet när det överlappar det mottagande elementet. Resultatet visas i figuren:

Fäst till elementets kanter

Med hjälp av snap-alternativet kan du säkerställa att det flyttade elementet "attraheras" till kanterna på elementen bredvid som det passerar. Detta alternativ accepterar en väljare som ett värde. Elementet som flyttas kommer att snäppa till kanterna på alla element som matchar den angivna väljaren. Ett exempel på användning av snap-alternativet ges nedan:

Kör jQuery UI-exempel #snapper, .draggable, .dropable (font-size: large; border: medium solid black; stoppning: 4px; width: 150px; text-align: center; bakgrundsfärg: ljusgrå; margin-bottom: 10px ;).droppbar (marginal-höger: 5px; höjd: 50px; bredd: 120px) #dropContainer (position: absolut; höger: 5px;) div span (position: relativ; topp: 25%) .dropable.active (kant: medium fast grön) .doppable.hover (bakgrundsfärg: ljusgrön) #snapper (position: absolut; vänster: 35%; kant: medium fast svart; bredd: 180px; höjd: 50px) $(function() ( $(" div.draggable").draggable(( snap: "#snapper, .doppable", snapMode: "both", snapTolerance: 50 )); $("#basket").dropable((activeClass: "active", hoverClass: "hovra" )); )); Varukorg Snap here Dra mig

När ett rörligt element närmar sig ett av de lämpliga elementen, "attraheras" det så att säga till det på ett sådant sätt att deras intilliggande kanter berör. För en sådan bindning kan du välja vilket element som helst, inte bara det mottagande elementet. I det här exemplet lade jag till ett div-element och ställde in snap-alternativet till ett värde som väljer det elementet såväl som det mottagande elementet i dokumentet.

Det finns ett par hjälpalternativ som låter dig anpassa förankringsbeteendet för element mer exakt. En av dem är snapMode-alternativet. Med dess hjälp kan du specificera typen av bindning. Följande värden är tillåtna: inre(snäpp till elementens inre kanter), yttre(snäpp till ytterkanterna av element) och både(snäpp till alla kanter; standard).

Alternativet snapTolerance låter dig specificera hur långt det flytande elementet måste närma sig kanten på målelementet innan snappning inträffar. Standardvärdet är 20, vilket betyder 20 pixlar. Exemplet använder ett värde på 50, vilket motsvarar ett snäpp på ett större avstånd. Det är mycket viktigt att välja rätt värde för detta alternativ. Om snapTolerance-värdet är för lågt kanske användaren inte märker snapping-effekten, och om det är för högt kommer elementet som flyttas att börja göra oväntade hopp och snappa till avlägsna element.

Användning av teknik dra och släpp(dra och släpp) låter användaren flytta olika objekt från ett till ett annat, till exempel element i en lista till en annan. För att göra detta måste du använda två kontroller: diskbänk och källa. Mottagaren är det objekt som kommer att ta emot källobjektet (objektet som flyttas).

Händelser som inträffar under förflyttning av objekt listas nedan i den ordning de inträffar.

OnStartDrag(typ TStartDragEvent) - i början av operationen, genererad av källobjektet. Parametrar som skickas till händelsehanteraren: DragObject-mottagarobjekt (TDragObject-typ), Source-objekt (TObject-typ).

OnDragOver(typ TDragOverEvent) - skapar ett mottagarobjekt när ett släpat objekt är över det. Parametrar som skickas till händelsehanteraren: mottagarobjekt Avsändare (typ TObject), källobjekt Källa (typ TObject), rörelsetillstånd State (typ TDragState), X och Y (typ heltal) - nuvarande koordinater för muspekaren, Acceptera ( typ boolean ) tecken på bekräftelse av flyttoperationen. Rörelsetillståndet gör det tydligt om föremålet som flyttas befinner sig i mottagarområdet, rör sig i det eller har lämnat det. De angivna parametrarna gör att målobjektet kan acceptera eller avvisa källobjektet. Acceptera parametern är inställd på Trye om flyttoperationen accepteras, annars är den satt till False.

onDragDrop (typ TDragDropEvent) - genereras av mottagarobjektet när det dragna objektet släpps på det. Händelsehanteraren skickas de aktuella koordinaterna för muspekaren, avsändarens mottagarobjekt (TObject-typ) och det ursprungliga rörelseobjektet Source (TObject-typ).

onEndDrag (EndDragEvent-typ) - Ökas när en dragoperation slutförs. X- och Y-koordinaterna för den punkt där källavsändarobjektet och mottagarmålobjektet skickas till händelsehanteraren.

För att skapa en dra och släpp räcker det att implementera två händelser: OnDragDrop och OnDragOver med egenskapen DragMode inställd på dmAutomatic. Annars måste starten av dragoperationen, BeginDrag-metoden, kodas av programmeraren.

För att konsolidera materialet kommer vi att skapa följande applikation. Placera panelkomponenten på formuläret. Ställ in egenskapen DragMode för Object Inspector till dmAutomatic. Låt oss välja formulärobjektet och använda objektgranskaren för att skapa följande händelser:

Procedur TForm1.FormDragOver(Sändare, Källa: TObject; X, Y: Heltal; Tillstånd: TDragState; var Acceptera: Boolean); börja om Källa = Panel1 sedan Acceptera:= Sant annars Acceptera:= Falskt; slutet; procedure TForm1.FormDragDrop(Sändare, Källa: TObject; X, Y: Heltal); börja Panel1.Left:= X; Panel1.Top:= Y; slutet;

Nu genom att starta programmet och klicka på musknappen ovanför panelen kan vi flytta panelobjektet genom hela formuläret.

Summa summarum: vi bekantade oss med tekniken dra och släpp(dra och släpp) och använde det i praktiken.

Dra och släpp-tekniker har utvecklats under många år. Det är ingen överraskning att med det ökande antalet programmerare som utvecklar plugins med öppen källkod (som jQuery), återupplivas gamla metoder. JavaScript-biblioteket är mycket lyhört och erbjuder många förbättringar i denna tid av webbteknologi.

I den här handledningen kommer vi att göra ett skript som du kan använda för att skapa dynamiska dra och släpp-rektanglar på din webbplats. Processen hanteras av jQuery. Sådana skript sparar tid genom att tillhandahålla färdiga funktioner! Och dra-och-släpp-biblioteket kan användas i andra projekt.

Förbereder innehåll

Först och främst, låt oss förbereda en liten webbplats för projektet. I projektmappen måste du skapa två kataloger med de anmärkningsvärda namnen "js" och "css" och en tom fil index.html. Koden kommer att vara mycket enkel, så att det finns en tydlig uppfattning om arbetet, och det finns en poäng för vidareutveckling.

Nedan finns koden för vår HTML-fil. I kapitel huvud vi inkluderar 3 skript. Det huvudsakliga jQuery-skriptet kommer att laddas från Google Code-servern. vår stilfil style.css ingår också, som innehåller huvudegenskaperna för formning utseende vårt dokument.

Dra mig Ja, ja. Precis jag. Du kan dra mig också ( zIndex: 200, opacitet: .9 )

P.S.: du kan lämna mig var som helst!

Invändigt avsnitt kropp endast två block är placerade div, som innehåller båda rektanglarna. Koden är ganska enkel och begriplig. Inuti varje rektangel finns rubriker med klasserna hanterare och hanterare2. Detta är viktigt eftersom varje rektangel beter sig annorlunda när du drar.


Installerar CSS

HTML-koden är väldigt enkel. Om du förstår den grundläggande uppmärkningen kommer CSS-stilarna inte heller att vara svåra. Främst definierade marginaler, stoppningar och färger.

Body,html ( font-family:Calibri, sans-serif; background:#eaf3fb; font-size:12px; height:1000px; line-height:18px; ) p ( höjd:30px; )

Väljare body,html används endast för demosidan. Och allt innehåll är placerat i två dragbara rektanglar.

Dv1 ( width:200px; background-color:#eff7ff; border:1px solid #96c2f1; position:absolute; left:100px; top:100px; ) .dv1 h2 (bakgrundsfärg:#b2d3f5; padding:5px; font- familj:Georgia, "Times New Roman", Times, serif; font-size:1.0em; text-transform:versaler; font-weight:bold; color:#3a424a; margin:1px; cursor:move; ) .dv1 div ( padding:5px; margin-bottom:10px; ) .dv2 ( bakgrundsfärg:#f6ebfb; border:1px solid #a36fde; width:550px; position:absolute; cursor:move; left:400px; top:230px; ) .dv2 h2 ( background-color:#eacfe9; letter-spacing:-0.09em; font-size:1.8em; font-weight: bold; padding:15px; margin:1px; color:#241f24; cursor:move; ) .dv2 .content2 ( padding:5px; margin-bottom:10px; )

För både klasserna .dv1 och .dv2 använder vi absolut positionering. Detta är inte nödvändigt och förmodligen inte det mest Det bästa sättet för att placera dragbara rektanglar. Men för vårt exempel är denna positionering vettig, eftersom varje gång sidan uppdateras installeras rektanglarna på vissa ställen.

Även typsnitt och färger är olika för rektanglarna för att göra det lättare att se skillnaden.

I övrigt är rubrikerna och innehållet i blocken nästan identiska. Om du ska kopiera stilar till ditt projekt, ändra namnen innan du börjar. I vissa fall är det mer meningsfullt att använda ID:n istället för klasser, till exempel när man använder dra-och-släpp-tekniken för ett specifikt block.

Parsar JavaScript

Två JavaScript-filer innehåller all kod som behövs för att det ska fungera. Vi kommer att utelämna detaljerna för att arbeta med jQuery, eftersom detta ligger utanför lektionens omfattning. Låt oss vara uppmärksamma på filen jquery.dragndrop.js.

Rad 22 definierar dragfunktionen.

$.fn.Drags = function(opts) ( var ps = $.extend(( zIndex: 20, opacitet: .7, hanterare: null, onMove: function() ( ), onDrop: function() ( ) ), opts );

Detta ställer in returvariabeln och initialiseringsdata för Drag. Denna metod används mycket ofta när man arbetar med jQuery för att skicka alternativ till andra funktioner. Internt ställer vi in ​​variabler för alla tillgängliga alternativ för rektanglarna som dras.


Nästa kodstycke inkluderar händelsehanterare för variabeln dragndrop. Båda händelserna drag Och släppa anropsfunktioner som skickar händelseparametrar till dem. Dessa händelser inträffar när du trycker på musknappen för att dra ett objekt och sedan släpper det.

Var dragndrop = ( drag: function(e) ( var dragData = e.data.dragData; dragData.target.css(( vänster: dragData.left + e.pageX - dragData.offLeft, top: dragData.top + e.pageY - dragData.offTop )); dragData.handler.css((markör: "move" )); dragData.target.css ((markör: "move" )); dragData.onMove(e); ), drop: function( e) ( var dragData = e.data.dragData; dragData.target.css(dragData.oldCss); //.css(( "opacity": "" )); dragData.handler.css("cursor", dragData. oldCss.cursor); dragData.onDrop(e); $().unbind("mousemove", dragndrop.drag) .unbind("mouseup", dragndrop.drop); ) )

Våra funktioner manipulerar CSS-positioneringen av varje objekt. Att ändra den absoluta placeringen av dina objekt kommer inte att påverka hur din kod fungerar, eftersom varje JavaScript-funktion ändrar vilken stil som än är definierad för objektet.

Resten av koden kontrollerar hanteraren och gör kosmetiska ändringar i andra stilar. Här kan du lägga till ändringar av transparens, teckensnitt och teckensnittsfärg, eller lägga till nya stycken.

Dra/släpp funktioner

Den andra fn.js-filen innehåller mycket enkel kod. Vi väntar full belastning dokument, varefter vi kallar våra funktioner. Två instanser av funktionen är definierade Drag, som diskuterades tidigare.

Vi har två flyttbara block med klasserna .dv1 och .dv2. Om du behöver lämna ett flyttbart block, behöver du bara ta bort den andra delen av koden. Det är också enkelt att lägga till ytterligare ett rörligt block. Du behöver bara lägga till en ny funktion i den här filen.

Det första steget är att ställa in alternativen när funktionen anropas. Se till att ange hanterarens namn. Med den talar vi om för jQuery vilken hanterare som ska användas när musknappen trycks ned i ett visst område av dokumentet. Hanterarens namn kan vara en klass eller ett ID-attribut.

Vår första funktion har två händelsehanterare onMove och onDrop. Båda anropar nya funktioner som skickas till den aktuella händelsen som variabler. Det är här HTML-koden i rektangeln manipuleras för att uppdateras med varje rörelse. Detta är en fantastisk effekt för att demonstrera hur du kan styra en process med enkla jQuery-händelser.

I den andra funktionen använder vi z-index och opacitetsparametrar. Kan du lägga till andra CSS-egenskaper? men detta kräver omarbetning av JavaScript-koden så att inställningarna kontrolleras. Till exempel kan du skicka en annan typsnittsstil eller värden för höjden och bredden på en rörlig rektangel - ett mycket intressant trick!

Slutsats

Med lite arbete har vi nu ett fantastiskt dra-och-släpp-gränssnitt till vårt förfogande. jQuery ger enorma fördelar för utvecklare som är ivriga att använda gamla metoder i sina projekt.

Som ett resultat har vi inte bara funktioner för händelsehanterare, utan vi kan också skicka nya variabler till dragbara block. Detta öppnar nya möjligheter för kreativitet. Demonstrationen för lektionen innehåller endast en skiss av vad som kan göras med sådan kod.

Så kolla in jQuery-dokumentationen för att använda biblioteksfunktionerna.

För VCL-biblioteket har Borland implementerat sin egen version av Drag&Drop-gränssnittet (översatt som "dra och släpp"). Detta gränssnitt är internt - du kan skicka och ta emot alla Delphi-kontroller inuti formuläret (förutom själva formuläret) Det implementeras utan att använda motsvarande Windows API-funktioner - de måste användas när du organiserar kommunikation med andra uppgifter genom att dra och släppa.

Genom att klicka med vänster musknapp över en kontroll kan vi "dra" den till vilket annat element som helst. Ur en programmerares synvinkel innebär detta att i ögonblicken för att dra och släppa en nyckel genereras vissa händelser, som överför all nödvändig information - en pekare till det dragna objektet, markörens nuvarande koordinater etc. Mottagaren av händelserna är det element som markören för närvarande befinner sig på. Händelsehanteraren för en sådan händelse måste tala om för systemet om kontrollen tar emot sändningen eller inte. När knappen ovanför mottagningskontrollen släpps genereras ytterligare en eller två händelser, beroende på mottagarens beredskap.

CancelDrag Avbryter den aktuella dra-och-släpp- eller dra-och-docka-operationen.

Funktion FindDragTarget (const Pos: TPoint ; AllowDisabled: Boolean ): TControl ;

Funktionen returnerar ett objekt av basklassen TControl, som refererar till skärmens position med koordinaterna definierade av Pos-parametern. Denna funktion används för att fastställa den potentiella mottagaren av en dra-och-släpp- eller dra-och-docka-operation. Om det inte finns någon fönsterkontroll för den angivna positionen, returnerar funktionen noll . Parametern AllowDisabled avgör om inaktiverade objekt kommer att beaktas.

Funktion IsDragObject(Avsändare: TObject): Boolean;

Funktionen avgör om objektet som anges i parametern Sender är en avkomling av klassen TDragObject. Den här funktionen kan användas som Source-parameter i händelsehanterarna OnDragOver och OnDockOver för att avgöra om det släpade objektet kommer att accepteras. Funktionen IsDragObject kan också användas som Source-parameter i händelsehanterarna OnDragDrop och OnDockDrop för att korrekt tolka det dragna objektet.

Egenskaper DragMode, DragCursor, metoder BeginDrag, OnDragOver, OnDragDrop, OnEndDrag, OnStartDrag, Accept parameter

Processen att dra information från ett objekt till ett annat med hjälp av musen används ofta i Windows. Du kan flytta filer mellan mappar, flytta själva mapparna osv.

Alla egenskaper, metoder och händelser associerade med dra-och-släpp-processen definieras i klassen TControl, som är stamfadern till alla Delphis visuella komponenter. Därför är de gemensamma för alla komponenter.

Starten av att dra bestäms av egenskapen DragMode, som kan ställas in vid designtidpunkten eller programmässigt lika med dmManual eller dmAutomatic. Värdet dmAutomatic anger om dragprocessen ska börja automatiskt när användaren trycker en musknapp över en komponent. Men i det här fallet inträffar inte OnMouseDown-händelsen som är kopplad till att användaren klickar på musknappen alls för den här komponenten.

Gränssnittet för att överföra och ta emot komponenter dök upp för ganska länge sedan. Det tillåter två kontroller att interagera medan programmet körs. I detta fall kan alla nödvändiga operationer utföras. Trots den enkla implementeringen och den långvariga utvecklingen anser många programmerare (särskilt nybörjare) denna mekanism som obskyr och exotisk. Att använda Dra-och-släpp kan dock vara mycket användbart och lätt att implementera. Nu ska vi se till detta.

För att mekanismen ska fungera måste två kontroller konfigureras därefter. Den ena ska vara en källa (källa), den andra ska vara en mottagare (Target). I det här fallet rör sig källan inte någonstans utan registreras bara som sådan i mekanismen.

Tro mig, det räcker att helt enkelt konvertera X,Y-koordinaterna som skickas i parametrarna för OnDragOver- och OnDragDrop-händelserna till formkoordinater.

Arbeta med egenskaperna Vänster och Topp för den komponent som markören rör sig över. Låt mig ge dig ett enkelt exempel. Placera en Memo-komponent på formuläret och ställ in egenskapen Align till alTop. Placera en panel på formuläret, ställ även in egenskapen Align till alTop och ställ in egenskapen Height till ett litet värde, säg 6 eller 7 pixlar. Ställ DragMode till dmAutomatica och DragCursor till crVSplit. Placera en annan Memo-komponent och ställ in Align to alClient. Välj samtidigt båda Memo-komponenterna, panelen och skapa en gemensam OnDragOver-händelsehanterare som visas nedan:

Nyligen fick jag en idé om att börja utveckla ett spel för Android. Till att börja med bestämde jag mig för att skriva schack. Det verkade för mig att Dra och släpp-tekniken skulle vara perfekt för att implementera mekanismen för att flytta figurer. För den oinitierade noterar jag att dra och släpp-metoden är möjligheten att dra ett grafiskt objekt till ett annat och utföra en eller annan åtgärd efter att ha släppt det. Det enklaste exemplet är att ta bort en genväg från skrivbordet på din PC genom att dra den till papperskorgen. Genom att "slänga" etiketten i papperskorgen säger vi till systemet att vi vill tvinga dessa två objekt att interagera. Systemet tar emot vår signal och bestämmer vilken åtgärd det ska vidta. Dra och släpp har blivit utbredd på grund av dess intuitiva klarhet. Detta tillvägagångssätt stöds av vår erfarenhet av att interagera med verkliga objekt och fungerar utmärkt i en virtuell miljö. När det gäller schack är det tekniskt enklare att använda dra och släpp att bestämma cellen där användaren släpade pjäsen, eftersom det inte finns något behov av att beräkna cellnumret från koordinaterna för släpppunkten. Detta arbete kommer att tas över av den virtuella maskinen.

Syften med att använda Drag n Drop-teknik

Genom att använda dra och släpp-teknik kan jag lösa tre problem med liten ansträngning:

  • Framstegsvisualisering. När användaren rör vid en form och börjar flytta den runt på skärmen ersätts formen med en mindre design. Därmed förstår användaren att figuren fångas.
  • Jag begränsade rörelseområdet för figuren till storleken på brädan.
  • Om användaren släpper en bit på fel plats, bör den återgå till sin ursprungliga position.
  • Uppgifterna har beskrivits, låt oss börja implementera dem.

    ImageView-ersättning vid beröring

    Alla mina former är ImageView-objekt. Tyvärr visade det sig att implementeringen av Drag & Drop i Android inte tillåter "rakt ur lådan" att ersätta bilden av ett objekt när det berörs. Denna uppgift kan dock lösas helt med hjälp av API:et. Vi kommer att behöva utföra ett antal enkla steg:

  • Skapa ett DragShadowBuilder-objekt.
  • Anropa startDrag-metoden.
  • Dölj vår ImageView, som visar formen, genom att anropa metoden setVisibility med parametern View.INVISIBLE. Som ett resultat kommer endast DragShadowBuilder-objektet att finnas kvar på skärmen, vilket signalerar till användaren att formen har fångats.
  • Dessa åtgärder måste implementeras i OnTouchListner-hanteraren för ImageView-objektet. För att göra detta, låt oss åsidosätta onTouch-metoden:

    @ Override public boolean onTouch(View view, MotionEvent motionEvent) ( if (motionEvent. getAction() == MotionEvent. ACTION_DOWN) ( ClipData clipData= ClipData. newPlainText("" , "" ) ; View. DragShadowBuilder dsgSha new (view) ; view. startDrag(clipData, dsb, view, 0 ); view. setVisibility(View. INVISIBLE) ; return true ; ) else (retur false ; ) )

    Allt är väldigt enkelt. Så vi har sorterat ut bildbytet, låt oss gå vidare till nästa uppgift.

    Begränsa dragområdet för drag-släppfunktionen

    Det finns ett problem med att begränsa dragområdet. Poängen är att om du släpper en pjäs utanför brädet kommer inte drop-händelsen att inträffa, eftersom användaren släppte objektet på ett tomt utrymme och det finns inget för objektet att interagera med. Som ett resultat kommer figuren inte att återgå till sitt ursprungliga tillstånd och kommer att förbli dold för alltid. Jag tillbringade mycket tid med att läsa dokumentationen, men jag kunde fortfarande inte hitta ett sätt att begränsa dra-och-släpp-området för objekt. Insikten kom plötsligt. Jag behöver inte begränsa området alls, jag behöver veta om användaren släppte formen korrekt eller inte.

    Fastställande av korrekt frisättning
    Jag hittade svar på mina frågor i avsnittet "hantera drag-slut-händelser" på Android Developers-webbplatsen. Här är några viktiga punkter:

  • När användaren slutför dragningen genereras ACTION_DRAG_ENDED-händelsen i DragListeners-hanteraren.
  • I DragListener kan du få mer detaljerad information om dragoperationen genom att anropa metoden DragEvent.getResult().
  • Om DragListener returnerar true som svar på ACTION_DROP-händelsen kommer anropet till getResult också att returnera true, annars returneras false.
  • Så jag måste fånga upp händelsen ACTION_DRAG_ENDED och anropa getResult-metoden. Om det returnerar falskt, har användaren dragit biten från brädet och jag måste ställa in ImageView till synligt läge.

    @ Override public boolean onDrag(View view, DragEvent dragEvent) ( int dragAction= dragEvent. getAction() ; View dragView= (View) dragEvent. getLocalState() ; if (dragAction== DragEvent. ACTION_DRAG_EXITED) ( innehåller falseDragable)= if (dragAction== DragEvent. ACTION_DRAG_ENTERED) ( containsDragable= true ; ) else if (dragAction== DragEvent. ACTION_DRAG_ENDED) ( if (dropEventNotHandled(dragEvent) ) ( dragView. setVisibility(View. VISIBLE) else if (dragAction) ; = DragEvent. ACTION_DROP& amp;& amp; containsDragable) ( checkForValidMove((ChessBoardSquareLayoutView) view, dragView) ; dragView. setVisibility(View. VISIBLE) ; ) return true ; ) private boolean dropEventNotHandled return(dragEvent dragEvent! ) ;)

    Nu kan användaren släppa figuren var som helst, och inget dåligt kommer att hända.

    Definition av giltiga drag

    Den sista delen av artikeln ägnas åt att kontrollera giltigheten av det drag som användaren försöker göra. Innan jag diskuterar detta ämne i detalj kommer jag att göra en kort anteckning som förklarar strukturen för min ansökan. Schackbrädet representeras som en TableLayout, och varje cell är ett barn till en LinearLayout och har en OnDragListener.

    Dessutom hänvisar varje OnDragListener till ett "mediator"-objekt, som tar hand om interaktionen mellan spelobjekt och kommer ihåg positionen för den aktuella cellen.

    När användaren drar en bit över en cell är följande åtgärder möjliga:

  • Använd händelsen ACTION_DRAG_ENTERED för att ställa in variabeln 'containsDraggable' till true.
  • Använda händelsen ACTION_DRAG_EXITED för att ställa in variabeln 'containsDraggable' till false.
  • Använder händelsen ACTION_DROP för att fråga medlaren om det är acceptabelt att placera en bit i den här cellen.
  • Nedan finns koden som implementerar den beskrivna logiken

    @ Override public boolean onDrag(View view, DragEvent dragEvent) ( int dragAction= dragEvent. getAction() ; View dragView= (View) dragEvent. getLocalState() ; if (dragAction== DragEvent. ACTION_DRAG_EXITED) ( innehåller falseDragable)= if (dragAction== DragEvent. ACTION_DRAG_ENTERED) ( containsDragable= true ; ) else if (dragAction== DragEvent. ACTION_DRAG_ENDED) ( if (dropEventNotHandled(dragEvent) ) ( dragView. setVisibility(View. VISIBLE) else if (dragAction) ; = DragEvent.ACTION_DROP& amp;& amp; containsDragable) ( checkForValidMove((ChessBoardSquareLayoutView) view, dragView) ; dragView. setVisibility(View. VISIBLE) ; ) return true ; )

    Som du kan se, oavsett om flytten är giltig eller inte, överförs ImageView till det synliga tillståndet. Jag ville att användaren skulle se formen röra sig. Jag nämnde tidigare att en cell är ett barn till LayoutView. Detta görs för att göra det lättare att flytta ImageView från cell till cell. Nedan finns koden för metoden checkForValidMove, som visar hur ImageView rör sig.

    private void checkForValidMove(ChessBoardSquareLayoutView view, View dragView) ( if (mediator. isValidMove(view) ) ( ViewGroup owner= (ViewGroup) dragView. getParent() ; owner. removeView(dragView) ; view. addView(dragView) ; view. setGravity (Gravity. CENTER) ; view. showAsLanded() ; mediator. handleMove(view) ; ) )

    Jag hoppas att den här artikeln kommer att hjälpa dig när du utvecklar dina egna projekt.

    
    Topp