Generelle problemstillinger og teori om Dra og slipp-teknologi. Dra og slipp-teknologi i Android Se hva "Drag-og-slipp" er i andre ordbøker

182

I dette eksemplet velger vi et div-element og gjør det flyttbart ved å kalle draggable()-metoden på det. Som vist i figuren nedenfor, i det åpnede dokumentet tar elementet sin vanlige posisjon, men etter det kan det flyttes med musepekeren til et hvilket som helst sted i nettleservinduet:

Muligheten til å dra og slippe elementer er nyttig i seg selv, men den er enda mer nyttig når den brukes sammen med Slippbar-interaksjonen, som beskrives nedenfor.

Dragbar interaksjon oppnås utelukkende ved bruk av spesifikke HTML-markeringer og CSS-stiler. Dette betyr at denne funksjonaliteten vil fungere i nesten alle nettlesere, men elementene som er utstyrt med den vil ikke kunne fungere med lignende native dra-og-slipp-verktøy operativsystemer.

Dra-og-slipp-operasjoner definert av HTML5-spesifikasjonen implementeres vanligvis ved bruk av opprinnelige operativsystemmekanismer. Hvis du bruker dra-og-slipp-mekanismen jQuery UI, er det bedre å deaktivere tilsvarende HTML5-funksjoner for å unngå konflikter. For å gjøre dette, sett det drabare attributtet til body-elementet i dokumentet til false.

Sette opp Draggable-interaksjonen

Det er mange tilpasningsalternativer for Draggable-interaksjoner. De viktigste egenskapene, som diskuteres i de følgende avsnittene, er vist i tabellen nedenfor:

Dragbare interaksjonsegenskaper Eiendomsbeskrivelse
akser Begrenser muligheten til å bevege seg i visse retninger. Standardverdien er usann, noe som betyr ingen begrensning, men du kan også spesifisere verdien "x" (kun flytt langs X-aksen) eller "y" (flytte kun langs Y-aksen)
Begrensning Begrenser plasseringen av elementet som flyttes til et bestemt område på skjermen. Typene støttede verdier er beskrevet i tabellen nedenfor, ved å bruke det tilsvarende eksemplet. Standardverdien er usann, noe som betyr ingen begrensninger
forsinkelse Angir hvor lenge et element må dras før det flyttes. Standardverdien er 0, som betyr ingen forsinkelse
avstand Definerer avstanden brukeren må dra et element fra startposisjonen før det faktisk beveger seg. Standardverdien er 1 piksel
Nett Tvinger snapping av det flyttede elementet til rutenettcellene. Standardverdien er falsk, noe som betyr ingen binding
Begrensende bevegelsesretninger

Det er flere måter du kan begrense et elements bevegelse til bestemte retninger. Den første er å bruke aksealternativet, som lar deg begrense bevegelsesretningen til X- eller Y-aksen. Et eksempel på dette er vist nedenfor:

... div.dragElement (font-size: large; border: thin solid black; padding:16px; width: 8em; text-align: center; background-color: lightgrå; margin: 4px ) $(function() ( $ (".dragElement").draggable(( akse: "x")).filter("#dragV").draggable("alternativ", "akse", "y"); )); Dra vertikalt Dra horisontalt Kjør eksempel

I dette eksemplet definerer vi to div-elementer, velger dem ved hjelp av jQuery, og kaller draggable()-metoden. Som et argument for denne metoden sender vi et objekt som i utgangspunktet begrenser bevegelsen av begge div-elementene til retningen langs X-aksen. Ved å bruke jQuery filter()-metoden kan vi velge dragV-elementet uten at jQuery søker i hele dokumentet igjen og sett det til en annen tillatt bevegelsesretning - langs Y-aksen. Dermed får vi et dokument der det ene div-elementet kun kan dras i vertikal retning, og det andre - bare i horisontal retning. Resultatet er vist i figuren:

Begrenser det tillatte området for elementbevegelse

Du kan også begrense området på skjermen der du kan dra et element. For å gjøre dette, bruk inneslutningsalternativet. Verdiformatene som kan spesifiseres i dette alternativet er beskrevet i tabellen nedenfor:

Et eksempel på bruk av inneslutningsalternativet er gitt nedenfor:

... div.dragElement (font-size: large; border: thin solid black; padding:16px; width: 8em; text-align: center; background-color: lightgrå; margin: 4px ) #container ( kantlinje: medium dobbel svart; bredde: 700px; høyde: 450px) $(function() ( $(".dragElement").draggable(( containment: "parent" )).filter("#dragH").draggable("option", " akse", "x"); )); Dra horisontalt Dra inn i overordnet Kjør eksempel

I dette eksemplet er begge elementene begrenset i deres evne til å bevege seg slik at de bare kan dras innenfor deres overordnede element, som er en div med fast størrelse. En av div-ene som blir flytende har den ekstra begrensningen å bli flytende ved å bruke akse-alternativet ved at den bare kan bevege seg horisontalt innenfor overordnet. Resultatet er illustrert i figuren:

Begrenser muligheten til å flytte et element til rutenettceller

Rutenettalternativet lar deg angi bindingen av det flyttede elementet til rutenettceller. Dette alternativet tar som en verdi en matrise med to elementer som spesifiserer bredden og høyden på rutenettcellene i piksler. Et eksempel på bruk av rutenettalternativet er gitt nedenfor:

... #draggable (font-size: x-large; border: thin solid black; width: 5em; text-align: center; padding:10px) $(function() ( $("#draggable").draggable( ( Nett: )); )); Dra meg Kjør eksempel

Dette eksemplet spesifiserer et rutenett med celler 100 piksler brede og 50 piksler høye. Når du drar et element, "hopper" det fra en (usynlig) celle til en annen. Snapeffekten er et godt eksempel på hvordan interaksjonsfunksjonalitet kan brukes, men det er vanskelig å formidle ved hjelp av skjermbilder.

Du kan lage en snap-effekt for bare én retning ved å sette den frie bevegelsesaksen til 1. Hvis du for eksempel setter rutenettet til , vil elementet feste seg til 100 piksler brede rutenettceller når det flyttes horisontalt, men vil bevege seg fritt vertikalt.

Flytteforsinkelse

Det er to alternativer som lar deg forsinke å dra et bevegelig element. Forsinkelsesalternativet lar deg spesifisere hvor lang tid, i millisekunder, som brukeren må dra musepekeren før elementet faktisk flyttes. En annen type forsinkelse er gitt av avstandsalternativet, som spesifiserer avstanden i piksler som brukeren må dra musepekeren før den blir fulgt av et element.

Et eksempel på bruk av begge innstillingene er gitt nedenfor:

... #time, #distance (font-size: large; border: thin solid black; polstring: 10px; width: 120px; text-align: center; background-color: lightgrå; margin: 4px; ) $(function( ) ( $("#time").draggable(( forsinkelse: 1000 )) $("#distance").draggable(( avstand: 150 )) )); Blokk med tidsforsinkelse Blokk med minimumsdistanse Løpseksempel

I dette eksemplet er det to bevegelige elementer, hvorav det ene er forsinket ved bruk av forsinkelsesalternativet, og det andre er forsinket med avstandsalternativet.

I tilfelle av en forsinkelse, spesifisert av forsinkelsesalternativet, må brukeren dra i en spesifisert tidsperiode før den faktisk flytter elementet. I dette eksemplet er varigheten av denne perioden 1000 ms. Det er ikke nødvendig å flytte musen på dette tidspunktet, men gjennom hele forsinkelsesperioden må museknappen holdes nede, deretter kan elementet flyttes ved å bevege musen. Etter at forsinkelsestiden har utløpt, vil elementet som flyttes feste seg til musepekerens plassering, underlagt begrensningene pålagt av rutenettet, regionen og aksealternativene diskutert tidligere.

Avstandsalternativet har en lignende effekt, men i dette tilfellet må brukeren dra musepekeren minst et spesifisert antall piksler i en hvilken som helst retning fra elementets startplassering. Elementet som flyttes vil deretter hoppe til gjeldende pekerplassering.

Hvis du bruker begge innstillingene på samme element, vil det flyttede elementet ikke flytte før begge forsinkelseskriteriene er oppfylt, dvs. til et forsøk på å dra et element varer i en spesifisert tid og til musepekeren flytter et spesifisert antall piksler.

Bruk av drabare interaksjonsmetoder

Alle metodene som er definert for dragbar interaksjon er en del av settet med basismetoder du allerede har sett når du ser på widgets. Det er ingen metoder som er spesifikke for Draggable-interaksjon, så vi vil ikke dekke dem i detalj. Listen over tilgjengelige metoder er gitt i tabellen nedenfor:

Bruke Dragable Interaction Events

Interaction Draggable støtter et enkelt sett med hendelser som varsler deg når et element dras. Disse hendelsene er beskrevet i tabellen nedenfor:

Som med widget-hendelser, kan disse hendelsene også reageres på. Et eksempel på håndtering av start- og stopphendelser er gitt nedenfor:

... #draggable (font-size: x-large; border: tynn ensfarget svart; width: 190px; text-align: center; padding:10px) $(function() ( $("#draggable").draggable( ( start: function() ( $("#draggable").text("Dra meg..."), stopp: function() ( $("#draggable").text("Drag meg") ) )) ;)); Dra meg Kjør eksempel

Dette eksemplet bruker start- og stopphendelser til å endre tekstinnholdet i et element mens det dras. Denne fordelen skyldes det faktum at Draggables interaksjon implementeres utelukkende ved hjelp av HTML og CSS: du kan bruke jQuery til å endre tilstanden til et element som kan dras, selv når det beveger seg over skjermen.

Bruke slippbar interaksjon

Å dra et element alene kan være tilstrekkelig i noen situasjoner, men det er mest nyttig når det brukes sammen med Slippbar-interaksjonen.

Elementer som den slippbare interaksjonen har blitt brukt på (mottakselementer) får muligheten til å akseptere bevegelige elementer som er opprettet ved hjelp av den drabare interaksjonen.

Mottakselementer opprettes ved hjelp av droppable()-metoden, men for å få nyttig funksjonalitet må du opprette hendelsesbehandlere blant de som er definert for denne typen interaksjon. Tilgjengelige arrangementer vises i tabellen nedenfor:

Slippbare interaksjonshendelser Begivenhetsbeskrivelse
skape Oppstår når en slippbar interaksjon brukes på et element
aktivere Oppstår når brukeren begynner å dra elementet som flyttes
deaktivere Oppstår når brukeren slutter å dra elementet som flyttes
over Oppstår når brukeren drar et flytbart element over et mottakende element (forutsatt at museknappen ikke er sluppet ennå)
ute Oppstår når brukeren drar elementet som flyttes utenfor mottakselementet
miste Oppstår når brukeren forlater elementet som flyttes på mottakerelementet

Et eksempel på å lage et enkelt mottakselement der det er definert en enkelt slipphendelsesbehandler, er gitt nedenfor:

... #dragbar, #slippbar (font-size: large; border: thin solid black; polstring: 10px; width: 100px; text-align: center; bakgrunnsfarge: lysegrå; margin: 4px;) #dropable (polstring) : 20px; posisjon: absolutt; høyre: 5px;) $(function() ( $("#draggable").draggable(); $("#doppable").dropable(( drop: function() ( $(" #draggable").text("Venstre") ) )); )); La meg være her Dra meg Kjør eksempel

Dette eksemplet legger til et div-element til dokumentet hvis tekstinnhold er representert av strengen "Leave here." Vi velger dette elementet ved å bruke jQuery og kaller dropable()-metoden, og sender det et innstillingsobjekt som definerer en behandler for drop-hendelsen. Svaret på denne hendelsen er å endre teksten til elementet som flyttes ved å bruke text()-metoden.

Dra-og-slipp-interaksjonen som er opprettet i dette eksemplet er enkel, men den gir en nyttig kontekst for å forklare hvordan Draggable og Dropable-interaksjonene fungerer sammen. De ulike stadiene i prosessen med å dra elementer er illustrert i figuren:

Det hele ser veldig enkelt ut. Vi drar elementet som flyttes til det er over mottakselementet og slipper det. Elementet som slippes forblir der det ble igjen, og tekstinnholdet endres som svar på slipphendelsen. De følgende delene viser hvordan du bruker andre slippbare interaksjonshendelser for å forbedre brukeropplevelsen.

Belysning av objektmottakende objekt

Ved å bruke aktiverings- og deaktiveringshendelsene kan du markere målmottaksobjektet når brukeren begynner prosessen med å dra et element. I mange situasjoner er denne ideen svært fruktbar fordi den gir brukeren pålitelig veiledning om hvilke elementer som er en del av dra-og-slipp-modellen. Et tilsvarende eksempel er gitt nedenfor:

... $(function() ( $("#draggable").draggable(); $("#doppable").dropable(( drop: function() ( $("#draggable").text("Left ") ), activate: function() ( $("#doppable").css(( kantlinje: "middels dobbel grønn", bakgrunnsfarge: "lightGreen" )); ), deaktiver: function() ( $("#doppable ").css("kant", "").css("bakgrunnsfarge", ""); ) )); )); ...Kjør eksempel

Så snart brukeren begynner å dra et element, utløses aktiveringshendelsen knyttet til mottakerelementet vårt, og behandlerfunksjonen bruker css()-metoden for å endre CSS-egenskapene for kant- og bakgrunnsfarge til det elementet. Som et resultat blir målmottakselementet uthevet, noe som indikerer for brukeren at det er en forbindelse mellom det og elementet som flyttes.

Deaktiver-hendelsen brukes til å fjerne CSS-egenskapsverdier fra mottakerelementet og returnere det til den opprinnelige tilstanden, så snart brukeren slipper museknappen. (Denne hendelsen oppstår hver gang å dra et element stopper, uavhengig av om elementet som dras blir liggende på mottakerelementet eller ikke.) Denne prosessen er illustrert i figuren:

Håndtering av overlappende elementer

Dra-og-slipp-teknologi kan forbedres ved å legge til over- og uthendelseshåndtering. Overhendelsen oppstår når 50 % av elementet som flyttes er over en hvilken som helst del av mottakerelementet. Ut-hendelsen oppstår når tidligere overlappende elementer ikke lenger overlapper hverandre. Et eksempel på responsen på disse hendelsene er gitt nedenfor:

$(function() ( $("#draggable").draggable(); $("#doppable").dropable(( drop: function() ( $("#draggable").text("Left") ) , activate: function() ( $("#dropable").css(( kantlinje: "middels dobbel grønn", bakgrunnsfarge: "lightGreen" )); ), deaktiver: function() ( $("#doppable"). css("border", "").css("bakgrunnsfarge", ""); ), over: function() ( $("#doppable").css(( kantlinje: "middels dobbel rød", bakgrunnsfarge : "rød" )); ), ut: function() ( $("#doppable").css("border", "").css("bakgrunnsfarge", ""); ) )); ) ); Kjør eksempel

De samme behandlerfunksjonene brukes her som i forrige eksempel, men i dette tilfellet er de knyttet til over- og ut-hendelsene. Når mottakerelementet overlapper minst 50 % av elementet som flyttes, er det omsluttet av en ramme og bakgrunnsfargen endres, som vist i figuren:

Denne grensen på 50 % kalles overlappingsterskelen (toleranse), hvis verdi kan settes når du oppretter mottakselementet, som vil bli vist senere.

Sette opp slippbar interaksjon

Slippbar-interaksjonen har en rekke egenskaper som du kan endre for å tilpasse virkemåten. Disse egenskapene er oppført i tabellen nedenfor:

Slippbare interaksjonsegenskaper Eiendomsbeskrivelse
funksjonshemmet Hvis dette alternativet er sant, er funksjonaliteten for slippbar interaksjon i utgangspunktet deaktivert. Standardverdien er falsk
aksepterer Begrenser settet med bevegelige elementer som mottakerelementet vil reagere på. Standardverdien er *, som samsvarer med ethvert element
activeClass Definerer en klasse som vil bli tildelt som svar på aktiveringshendelsen og fjernet som svar på deaktiveringshendelsen
hoverClass Definerer en klasse som vil bli tildelt som svar på en overhendelse og fjernet som svar på en ut-hendelse
toleranse Definerer minimumsgraden av overlapping der en overhendelse oppstår
Begrensning av tillatte elementer som skal flyttes

Du kan begrense settet med slippbare elementer som vil bli akseptert av et element med slippbar ved å bruke aksepteralternativet. Verdien av akseptalternativet bør settes til en velger. Som et resultat vil slippbare interaksjonshendelser bare oppstå hvis elementet som flyttes samsvarer med den angitte velgeren. Et tilsvarende eksempel er gitt nedenfor:

... .draggable, #dropable (font-size: large; border: thin solid black; padding: 10px; width: 100px; text-align: center; background-color: lightgray; margin: 4px;) #dropable (padding) : 20px; posisjon: absolutt; høyre: 5px;) $(function() ( $(".draggable").draggable(); $("#doppable").doppable(( drop: function(event, ui) ( ui.draggable.text("Left") ), activate: function() ( $("#doppable").css(( kantlinje: "middels dobbel grønn", bakgrunnsfarge: "lightGreen" )); ), deaktiver: funksjon () ( $("#dropable").css("border", "").css("bakgrunnsfarge", ""); ), godta: "#drag1" )); )); La her Element 1 Element 2 Kjør eksempel

I dette eksemplet er det to dragbare elementer med ID-er drag1 og drag2. Når vi oppretter et mottakselement, bruker vi aksept-alternativet, som vi indikerer at kun drag1-elementet vil være et akseptabelt element som skal flyttes.

Når du drar drag1-elementet, vil du se samme effekt som i de forrige eksemplene. På passende tidspunkt vil aktiverings-, deaktiverings-, over- og ut-hendelsene utløses for det mottakende elementet. Samtidig, hvis du drar et drag2-element som ikke samsvarer med velgeren som er spesifisert i akseptparameteren, vil ikke disse hendelsene bli utløst. Dette elementet kan beveges fritt, men det vil ikke bli oppfattet av mottakerelementet.

Legg merke til endringen i hvordan vi velger et akseptabelt flytbart element for å kalle tekst()-metoden. Når det bare var ett bevegelig element i dokumentet, var id-attributtet nok for dette:

Slipp: function() ( $("#draggable").text("Left") ),

I dette eksemplet er det to flytbare elementer, og å velge etter id-attributt vil ikke gi det ønskede resultatet, siden teksten i dette tilfellet alltid vil endre seg i det samme flytbare elementet, uavhengig av hvilket som er akseptabelt for det mottakende elementet.

Løsningen er å bruke ui-objektet, som jQuery UI gir som et tilleggsargument til hver hendelsesbehandler. Den dragbare egenskapen til et ui-objekt returnerer et jQuery-objekt som inneholder elementet som brukeren drar eller prøver å slippe på målelementet, slik at ønsket element kan velges slik:

Slipp: function(event, ui) ( ui.draggable.text("Left") ),

Endring av overlappingsterskel

Som standard inntreffer overhendelsen bare når minst 50 % av elementet som flyttes overlapper det mottakende elementet. Mengden av denne terskeloverlappingen kan endres ved å bruke toleransealternativet, som kan ta verdiene vist i tabellen nedenfor:

De to verdiene jeg bruker oftest er passform og berøring fordi de gir mest mening for brukerne. Jeg bruker passform når det drade elementet må forbli i området til mottakselementet det ble flyttet til, og trykker når det drade elementet må gå tilbake til sin opprinnelige posisjon (et eksempel vil bli gitt nedenfor). Et eksempel på bruk av tilpasnings- og berøringsparametrene er gitt nedenfor:

Kloneverdien forteller jQuery UI å lage en kopi av elementet som flyttes, sammen med alt innholdet, og bruke det resulterende resultatet som et hjelpeelement. Resultatet er vist i figuren:

Hjelpeelementet fjernes når brukeren slipper museknappen over elementet som flyttes, og lar elementet som flyttes og mottakerelementet være i sine opprinnelige posisjoner.

Som vist på figuren, forblir det originale elementet som flyttes på plass og bare hjelpeelementet beveger seg rundt på skjermen etter musepekeren. Hvis størrelsen på det flyttede elementet er stort, som i vårt eksempel, dekker det resten av dokumentelementene, slik at det vil være vanskelig for brukeren å spore posisjonen til mottakerelementet. Dette problemet kan løses ved å angi funksjonen som verdien av hjelpealternativet, som vist i eksemplet nedenfor:

... $(function() ( $("div.draggable")..png"/>") ) )); $("#basket").doppable((activeClass: "active", hoverClass: "hover" )); )); ...Kjør eksempel

Når brukeren begynner å dra et element, kaller jQuery UI funksjonen spesifisert av hjelpeparameteren og bruker det returnerte elementet som objektet som skal dras. I dette tilfellet bruker jeg jQuery for å lage img-elementet. Resultatet er vist i figuren:

Et lite bilde fungerer som en proxy for elementet som flyttes, noe som gjør det mye lettere å holde styr på andre elementer i dokumentet.

Ui-objektet som jQuery-brukergrensesnittet sender til slippbare interaksjonshendelser inneholder en hjelpeegenskap, og denne egenskapen kan brukes til å manipulere hjelperen mens den dras. Et eksempel på bruk av denne egenskapen i forbindelse med over- og ut-hendelser er gitt nedenfor:

... $(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", "") ) )); )); ...

Her brukes over- og ut-hendelsene og ui.helper-egenskapen til å vise en kant rundt hjelpeelementet når det overlapper mottakerelementet. Resultatet er vist i figuren:

Fest til elementkanter

Ved å bruke snap-alternativet kan du sikre at det flyttede elementet blir "tiltrukket" til kantene av elementene ved siden av det passerer. Dette alternativet godtar en velger som en verdi. Elementet som flyttes vil feste seg til kantene på ethvert element som matcher den angitte velgeren. Et eksempel på bruk av snap-alternativet er gitt nedenfor:

Kjør jQuery UI-eksempel #snapper, .draggable, .dropable (font-size: large; border: medium solid black; padding: 4px; width: 150px; text-align: center; background-color: lightgray; margin-bottom: 10px ;).slippbar (margin-høyre: 5px; høyde: 50px; bredde: 120px) #dropContainer (posisjon: absolutt; høyre: 5px;) div span (posisjon: relativ; topp: 25%) .dropable.active (border: medium ensfarget grønn) .doppable.hover (bakgrunnsfarge: lysegrønn) #snapper (posisjon: absolutt; venstre: 35%; kantlinje: middels ensfarget svart; bredde: 180px; høyde: 50px) $(function() ( $(" div.draggable").draggable(( snap: "#snapper, .doppable", snapMode: "both", snapTolerance: 50 )); $("#basket").dropable((activeClass: "active", hoverClass: "sveve" )); )); Handlevogn Snap here Dra meg

Når et bevegelig element nærmer seg et av de passende elementene, blir det så å si "tiltrukket" av det på en slik måte at deres tilstøtende kanter berører hverandre. For en slik binding kan du velge hvilket som helst element, ikke bare mottakerelementet. I dette eksemplet la jeg til et div-element og satte snap-alternativet til en verdi som velger det elementet så vel som det mottakende elementet i dokumentet.

Det er et par hjelpealternativer som lar deg tilpasse forankringsatferden til elementer mer presist. En av dem er snapMode-alternativet. Med dens hjelp kan du spesifisere type binding. Følgende verdier er tillatt: indre(feste til de indre kantene av elementene), ytre(feste til ytterkantene av elementer) og både(fest til alle kanter; standard).

SnapTolerance-alternativet lar deg spesifisere hvor langt det flytende elementet må nærme seg kanten av målelementet før snapping skjer. Standardverdien er 20, som betyr 20 piksler. Eksemplet bruker en verdi på 50, som tilsvarer et knips på en større avstand. Det er veldig viktig å velge riktig verdi for dette alternativet. Hvis snapTolerance-verdien er for lav, kan det hende at brukeren ikke legger merke til snapping-effekten, og hvis den er for høy, vil elementet som flyttes begynne å gjøre uventede hopp, og snappe til fjerne elementer.

Bruk av teknologi dra og slipp(dra og slipp) lar brukeren flytte ulike objekter fra ett til et annet, for eksempel elementer fra en liste til en annen. For å gjøre dette må du bruke to kontroller: vask og kilde. Mottakeren er objektet som vil motta kildeobjektet (objektet som flyttes).

Hendelser som oppstår under bevegelse av objekter er listet opp nedenfor i den rekkefølgen de oppstår.

OnStartDrag(skriv TStartDragEvent) - i begynnelsen av operasjonen, generert av kildeobjektet. Parametere som sendes til hendelsesbehandleren: DragObject-mottakerobjekt (TDragObject-type), Kildeobjekt (TObject-type).

OnDragOver(skriv TDragOverEvent) - oppretter et mottakerobjekt når et trukket objekt er over det. Parametere som sendes til hendelsesbehandleren: mottakerobjekt Sender (type TObject), kildeobjekt Kilde (type TObject), bevegelsestilstand State (type TDragState), X og Y (type heltall) - gjeldende koordinater til musepekeren, Accept ( type boolesk ) tegn på bekreftelse av flytteoperasjonen. Bevegelsestilstanden gjør det klart om objektet som flyttes er i mottakerområdet, beveger seg i det eller har forlatt det. De beståtte parameterne gjør at målobjektet kan godta eller avvise kildeobjektet. Accept-parameteren settes til Trye hvis flytteoperasjonen aksepteres, ellers settes den til False.

onDragDrop (type TDragDropEvent) - generert av mottakerobjektet når det drade objektet slippes på det. Hendelsesbehandleren sendes de gjeldende koordinatene til musepekeren, avsendermottakerobjektet (TObject-type) og det opprinnelige bevegelsesobjektet Kilde (TObject-type).

onEndDrag (EndDragEvent type) - Heves når en dra-operasjon fullføres. X- og Y-koordinatene til punktet der kildeavsenderobjektet og mottakermålobjektet sendes til hendelsesbehandleren.

For å lage en dra og slipp er det nok å implementere to hendelser: OnDragDrop og OnDragOver med DragMode-egenskapen satt til dmAutomatic. Ellers må starten av draoperasjonen, BeginDrag-metoden, kodes av programmereren.

For å konsolidere materialet lager vi følgende applikasjon. Plasser panelkomponenten på skjemaet. Sett DragMode-egenskapen til Object Inspector til dmAutomatic. La oss velge skjemaobjektet og bruke objektinspektøren til å lage følgende hendelser:

Prosedyre TForm1.FormDragOver(Sender, Kilde: TObject; X, Y: Heltall; State: TDragState; var Accept: Boolean); begynn hvis Kilde = Panel1 og deretter Godta:= Sant ellers Godta:= Usann; slutt; prosedyre TForm1.FormDragDrop(Sender, Kilde: TObject; X, Y: Heltall); begynne Panel1.Left:= X; Panel1.Topp:= Y; slutt;

Nå ved å starte programmet og klikke på museknappen over panelet, kan vi flytte panelobjektet gjennom hele skjemaet.

Hovedpoenget: vi ble kjent med teknologien dra og slipp(dra og slipp) og brukte det i praksis.

Dra og slipp-teknikker har utviklet seg over mange år. Det er ingen overraskelse at med det økende antallet programmerere som utvikler plugins med åpen kildekode (som jQuery), blir gamle metoder gjenopplivet. JavaScript-biblioteket er svært responsivt og tilbyr mange forbedringer i denne epoken med nettteknologi.

I denne opplæringen skal vi lage et skript som du kan bruke til å lage dynamiske dra-og-slipp-rektangler på nettstedet ditt. Prosessen administreres av jQuery. Slike skript sparer tid ved å tilby ferdige funksjoner! Og dra-og-slipp-biblioteket kan brukes i andre prosjekter.

Forbereder innhold

Først av alt, la oss lage en liten nettside for prosjektet. I prosjektmappen må du opprette to kataloger med de bemerkelsesverdige navnene "js" og "css" og en tom fil index.html. Koden vil være veldig enkel, slik at det er en klar idé om arbeidet, og det er et poeng for videre utvikling.

Nedenfor er koden for HTML-filen vår. I kapittel hode vi inkluderer 3 skript. Hoved-jQuery-skriptet vil bli lastet fra Google Code-serveren. stilfilen vår style.css er også inkludert, som inneholder hovedegenskapene for forming utseende vårt dokument.

Dra meg Ja, ja. Akkurat meg. Du kan dra meg også ( zIndex: 200, opasitet: .9 )

P.S.: du kan forlate meg hvor som helst!

Innvendig seksjon kropp kun to blokker er plassert div, som inneholder begge rektanglene. Koden er ganske enkel og forståelig. Inne i hvert rektangel er det overskrifter med klassebehandler og handler2. Dette er viktig fordi hvert rektangel oppfører seg forskjellig når du drar.


Installerer CSS

HTML-koden er veldig enkel. Hvis du forstår den grunnleggende markeringen, vil ikke CSS-stilene være vanskelige heller. Hovedsakelig definerte marger, polstringer og farger.

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

Velgere body,html brukes kun for demosiden. Og alt innholdet er plassert i to dragbare rektangler.

Dv1 ( width:200px; background-color:#eff7ff; border:1px solid #96c2f1; position:absolute; left:100px; top:100px; ) .dv1 h2 (bakgrunnsfarge:#b2d3f5; padding:5px; font- familie:Georgia, "Times New Roman", Times, serif; font-size:1.0em; text-transform:store bokstaver; font-weight:bold; color:#3a424a; margin:1px; cursor:move; ) .dv1 div ( padding:5px; margin-bottom:10px; ) .dv2 ( bakgrunnsfarge:#f6ebfb; border:1px solid #a36fde; width:550px; position:absolutt; 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; )

For begge klassene .dv1 og .dv2 bruker vi absolutt posisjonering. Dette er ikke nødvendig og sannsynligvis ikke det mest Den beste måten for å plassere drabare rektangler. Men for vårt eksempel er denne posisjoneringen fornuftig, siden hver gang siden oppdateres, installeres rektanglene på visse steder.

Også fontene og fargene er forskjellige for rektanglene for å gjøre det lettere å se forskjellen.

Ellers er overskriftene og innholdet i blokkene nesten identiske. Hvis du skal kopiere stiler inn i prosjektet ditt, endre navnene før du starter. I noen tilfeller er det mer fornuftig å bruke ID-er i stedet for klasser, for eksempel når du bruker dra-og-slipp-teknikken for en bestemt blokk.

Parsing JavaScript

To JavaScript-filer inneholder all koden som trengs for å få det til å fungere. Vi vil utelate detaljene rundt arbeid med jQuery, da dette er utenfor leksjonens omfang. La oss ta hensyn til filen jquery.dragndrop.js.

Linje 22 definerer Dra-funksjonen.

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

Dette setter returvariabelen og initialiseringsdata for Dra. Denne metoden er veldig vanlig når du arbeider med jQuery for å overføre alternativer til andre funksjoner. Internt setter vi variabler for alle tilgjengelige alternativer for rektanglene som dras.


Den neste kodebiten inkluderer hendelsesbehandlere for dragndrop-variabelen. Begge hendelsene dra Og miste kallefunksjoner som sender hendelsesparametere til dem. Disse hendelsene oppstår når du trykker på museknappen for å dra et objekt og deretter slipper det.

Var dragndrop = ( drag: function(e) ( var dragData = e.data.dragData; dragData.target.css(( venstre: 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åre funksjoner manipulerer CSS-posisjoneringen av hvert objekt. Endring av den absolutte plasseringen av objektene dine vil ikke påvirke hvordan koden din fungerer, siden hver JavaScript-funksjon endrer hvilken stil som er definert for objektet.

Resten av koden sjekker behandleren og gjør kosmetiske endringer i andre stiler. Her kan du legge til endringer i gjennomsiktighet, skrift og skriftfarge, eller legge til nye avsnitt.

Dra/slipp-funksjoner

Den andre fn.js-filen inneholder veldig enkel kode. Vi venter fullastet dokument, hvoretter vi kaller funksjonene våre. To forekomster av funksjonen er definert Dra, som ble diskutert tidligere.

Vi har to flyttbare blokker med klassene .dv1 og .dv2 . Hvis du trenger å forlate en flyttbar blokk, trenger du bare å fjerne den andre delen av koden. Det er også enkelt å legge til en annen flyttbar blokk. Du trenger bare å legge til en ny funksjon i denne filen.

Det første trinnet er å angi alternativene når du kaller opp funksjonen. Sørg for å angi behandlernavnet. Med den forteller vi jQuery hvilken behandler som skal brukes når museknappen trykkes i et bestemt område av dokumentet. Behandlernavnet kan være en klasse eller et ID-attributt.

Vår første funksjon har to hendelsesbehandlere onMove og onDrop. Begge kaller nye funksjoner som sendes til gjeldende hendelse som variabler. Det er her HTML-koden i rektangelet manipuleres for å oppdateres med hver bevegelse. Dette er en flott effekt for å demonstrere hvordan du kan kontrollere en prosess ved hjelp av enkle jQuery-hendelser.

I den andre funksjonen bruker vi z-indeksen og opasitetsparametere. Kan du legge til andre CSS-egenskaper? men dette vil kreve omarbeiding av JavaScript-koden slik at innstillingene kontrolleres. For eksempel kan du sende en annen skriftstil eller verdier for høyden og bredden til et bevegelig rektangel - et veldig interessant triks!

Konklusjon

Med litt arbeid har vi nå et flott dra-og-slipp-grensesnitt til rådighet. jQuery gir store fordeler for utviklere som er ivrige etter å bruke gamle metoder i sine prosjekter.

Som et resultat har vi ikke bare hendelsesbehandlerfunksjoner, men vi kan også sende nye variabler til dragbare blokker. Dette åpner for nye muligheter for kreativitet. Demonstrasjonen for leksjonen inneholder kun en skisse av hva som kan gjøres med slik kode.

Så sjekk ut jQuery-dokumentasjonen for å bruke bibliotekfunksjonene.

For VCL-biblioteket har Borland implementert sin egen versjon av Drag&Drop-grensesnittet (oversatt som "dra og slipp"). Dette grensesnittet er internt - du kan sende og motta alle Delphi-kontroller inne i skjemaet (bortsett fra selve skjemaet) Det implementeres uten å bruke de tilsvarende Windows API-funksjonene - de må brukes når du organiserer kommunikasjon med andre oppgaver ved å dra og slippe.

Ved å klikke med venstre museknapp over en kontroll kan vi "dra" den til et hvilket som helst annet element. Fra en programmerers synspunkt betyr dette at i øyeblikkene for å dra og slippe en nøkkel, genereres visse hendelser, som overfører all nødvendig informasjon - en peker til det drade objektet, gjeldende koordinater til markøren, etc. Mottakeren av hendelsene er elementet som markøren er plassert på. Hendelsesbehandleren for en slik hendelse må fortelle systemet om kontrollen mottar sendingen eller ikke. Når knappen over mottakerkontrollen slippes, genereres en eller to hendelser til, avhengig av mottakerens beredskap.

CancelDrag Avbryter gjeldende dra-og-slipp- eller dra-og-dok-operasjon.

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

Funksjonen returnerer et objekt av basisklassen TControl, som refererer til posisjonen til skjermen med koordinatene definert av Pos-parameteren. Denne funksjonen brukes til å bestemme den potensielle mottakeren av en dra-og-slipp- eller dra-og-dok-operasjon. Hvis ingen vinduskontroll eksisterer for den angitte posisjonen, returnerer funksjonen null . Parameteren AllowDisabled bestemmer om deaktiverte objekter skal tas i betraktning.

Funksjon IsDragObject(Sender: TObject): Boolsk;

Funksjonen bestemmer om objektet spesifisert i Sender-parameteren er en etterkommer av klassen TDragObject. Denne funksjonen kan brukes som kildeparameteren i hendelsesbehandlerne OnDragOver og OnDockOver for å bestemme om det drade objektet vil bli akseptert. IsDragObject-funksjonen kan også brukes som kildeparameter i hendelsesbehandlerne OnDragDrop og OnDockDrop for å tolke det drade objektet korrekt.

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

Prosessen med å dra informasjon fra ett objekt til et annet ved hjelp av musen er mye brukt i Windows. Du kan flytte filer mellom mapper, flytte selve mappene osv.

Alle egenskaper, metoder og hendelser knyttet til dra-og-slipp-prosessen er definert i TControl-klassen, som er stamfaderen til alle Delphi visuelle komponenter. Derfor er de felles for alle komponenter.

Starten på dra bestemmes av DragMode-egenskapen, som kan settes på designtidspunktet eller programmatisk lik dmManual eller dmAutomatic. Verdien dmAutomatic spesifiserer om draprosessen vil starte automatisk når brukeren trykker en museknapp over en komponent. I dette tilfellet forekommer imidlertid ikke OnMouseDown-hendelsen knyttet til at brukeren klikker på museknappen i det hele tatt for denne komponenten.

Grensesnittet for overføring og mottak av komponenter dukket opp for ganske lenge siden. Den lar to kontroller samhandle mens applikasjonen kjører. I dette tilfellet kan alle nødvendige operasjoner utføres. Til tross for den enkle implementeringen og langvarige utviklingen, anser mange programmerere (spesielt nybegynnere) denne mekanismen som obskur og eksotisk. Å bruke Dra-og-slipp kan imidlertid være svært nyttig og enkelt å implementere. Nå skal vi sørge for dette.

For at mekanismen skal fungere, må to kontroller konfigureres tilsvarende. Den ene skal være en kilde (Kilde), den andre skal være en mottaker (Target). I dette tilfellet beveger kilden seg ikke noe sted, men registreres kun som sådan i mekanismen.

Tro meg, det er nok å bare konvertere X,Y-koordinatene som sendes i parametrene til OnDragOver- og OnDragDrop-hendelsene til formkoordinater.

Arbeid med Venstre- og Toppegenskapene til komponenten som markøren beveger seg over. La meg gi deg et enkelt eksempel. Plasser en Memo-komponent på skjemaet og sett Align-egenskapen til alTop. Plasser et panel på skjemaet, sett også Align-egenskapen til alTop og sett Height-egenskapen til en liten verdi, for eksempel 6 eller 7 piksler. Sett DragMode til dmAutomatica og DragCursor til crVSplit. Plasser en annen Memo-komponent og sett Align to alClient. Velg samtidig begge Memo-komponentene, panelet og lag en felles OnDragOver hendelsesbehandler som vist nedenfor:

Nylig fikk jeg en idé om å begynne å utvikle et spill for Android. Til å begynne med bestemte jeg meg for å skrive sjakk. Det virket for meg som Drag and Drop-teknologien ville være perfekt for å implementere mekanismen for å bevege figurer. For de uinnvidde legger jeg merke til at dra og slipp-metoden er muligheten til å dra et grafisk objekt til et annet og utføre en eller annen handling etter å ha sluppet den. Det enkleste eksemplet er å slette en snarvei fra skrivebordet på PC-en ved å dra den til papirkurven. Ved å "kaste" etiketten i søpla, forteller vi systemet at vi ønsker å tvinge disse to objektene til å samhandle. Systemet mottar vårt signal og bestemmer hva det skal gjøre. Dra og slipp har blitt utbredt på grunn av dens intuitive klarhet. Denne tilnærmingen støttes av vår erfaring med å samhandle med virkelige objekter og fungerer utmerket i et virtuelt miljø. Når det gjelder sjakk, er det ved å bruke dra og slipp teknologisk enklere å bestemme cellen der brukeren drar brikken, siden det ikke er behov for å beregne cellenummeret fra koordinatene til utgivelsespunktet. Dette arbeidet vil bli overtatt av den virtuelle maskinen.

Formål med å bruke Drag n Drop-teknologi

Ved å bruke dra og slipp-teknologi kan jeg løse tre problemer med liten innsats:

  • Fremdriftsvisualisering. Når brukeren berører en form og begynner å flytte den rundt på skjermen, erstattes formen med en mindre design. Dermed forstår brukeren at figuren er fanget.
  • Jeg begrenset bevegelsesområdet til figuren til størrelsen på brettet.
  • Hvis brukeren slipper en brikke på feil sted, bør den gå tilbake til sin opprinnelige posisjon.
  • Oppgavene er skissert, la oss begynne å implementere dem.

    ImageView-erstatning ved berøring

    Alle figurene mine er ImageView-objekter. Dessverre viste det seg at implementeringen av Dra og slipp i Android ikke tillater "rett ut av boksen" å erstatte bildet av et objekt når det berøres. Denne oppgaven kan imidlertid løses fullstendig ved hjelp av API. Vi må utføre en rekke enkle trinn:

  • Lag et DragShadowBuilder-objekt.
  • Kall startDrag-metoden.
  • Skjul vår ImageView, som viser formen, ved å kalle opp setVisibility-metoden med parameteren View.INVISIBLE. Som et resultat vil bare DragShadowBuilder-objektet forbli på skjermen, noe som vil signalisere til brukeren at formen har blitt fanget.
  • Disse handlingene må implementeres i OnTouchListner-behandleren til ImageView-objektet. For å gjøre dette, la oss overstyre onTouch-metoden:

    @ Overstyr offentlig boolean onTouch(View view, MotionEvent motionEvent) ( if (motionEvent. getAction() == MotionEvent. ACTION_DOWN) ( ClipData clipData= ClipData. newPlainText("" , "" ) ; View. DragShadowBuilder dsb=ha (view) ; view. startDrag(clipData, dsb, view, 0 ); view. setVisibility(View. INVISIBLE) ; return true ; ) else (retur usant ; ) )

    Alt er veldig enkelt. Så, vi har sortert ut bildeerstatningen, la oss gå videre til neste oppgave.

    Begrense draområdet for dra-slipp-funksjonen

    Det er et problem med å begrense dragområdet. Poenget er at hvis du slipper en brikke utenfor brettet, vil ikke drop-hendelsen inntreffe, siden brukeren slapp objektet på et tomt rom, og det er ingenting for objektet å samhandle med. Som et resultat vil figuren ikke gå tilbake til sin opprinnelige tilstand og forbli skjult for alltid. Jeg brukte mye tid på å lese dokumentasjonen, men jeg kunne fortsatt ikke finne en måte å begrense dra-og-slipp-området til objekter. Innsikten kom plutselig. Jeg trenger ikke å begrense området i det hele tatt, jeg trenger å vite om brukeren har gitt ut formen riktig eller ikke.

    Bestemme riktig utgivelse
    Jeg fant svar på spørsmålene mine i delen "håndtering av drag end-hendelser" på nettstedet for Android-utviklere. Her er noen hovedpunkter:

  • Når brukeren fullfører dra, genereres ACTION_DRAG_ENDED-hendelsen i DragListeners-behandleren.
  • I DragListener kan du få mer detaljert informasjon om dra-operasjonen ved å kalle opp DragEvent.getResult()-metoden.
  • Hvis DragListener returnerer true som svar på ACTION_DROP-hendelsen, vil kallet til getResult også returnere true, ellers returnerer det false.
  • Så jeg må avskjære ACTION_DRAG_ENDED-hendelsen og kalle opp getResult-metoden. Hvis den returnerer falsk, har brukeren dratt brikken av brettet, og jeg må sette ImageView til synlig modus.

    @ Override public boolean onDrag(View view, DragEvent dragEvent) ( int dragAction= dragEvent. getAction() ; View dragView= (View) dragEvent. getLocalState() ; if (dragAction== DragEvent. ACTION_DRAG_EXITED) ( inneholder 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 dragEventNotHandled (DragEvent dragEvent! ) ;)

    Nå kan brukeren slippe figuren hvor som helst, og ingenting vondt vil skje.

    Definisjon av gyldige trekk

    Den siste delen av artikkelen er viet til å sjekke gyldigheten av trekket som brukeren prøver å gjøre. Før jeg diskuterer dette emnet i detalj, vil jeg lage et kort notat som forklarer strukturen til søknaden min. Sjakkbrettet er representert som en TableLayout, og hver celle er et barn av en LinearLayout og har en OnDragListener.

    I tillegg refererer hver OnDragListener til et "mediator"-objekt, som tar seg av interaksjonen til spillobjekter og husker posisjonen til den gjeldende cellen.

    Når brukeren drar et stykke over en celle, er følgende handlinger mulig:

  • Bruk av ACTION_DRAG_ENTERED-hendelsen til å sette 'containsDraggable'-variabelen til true.
  • Bruk av ACTION_DRAG_EXITED-hendelsen til å sette 'containsDraggable'-variabelen til false.
  • Bruk av ACTION_DROP-hendelsen til å spørre formidleren om det er akseptabelt å plassere en brikke i denne cellen.
  • Nedenfor er koden som implementerer den beskrevne logikken

    @ Override public boolean onDrag(View view, DragEvent dragEvent) ( int dragAction= dragEvent. getAction() ; View dragView= (View) dragEvent. getLocalState() ; if (dragAction== DragEvent. ACTION_DRAG_EXITED) ( inneholder 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, uansett om flyttingen er gyldig eller ikke, overføres ImageView til synlig tilstand. Jeg ville at brukeren skulle se formen bevege seg. Jeg nevnte tidligere at en celle er et barn av LayoutView. Dette gjøres for å gjøre det enklere å flytte ImageView fra celle til celle. Nedenfor er koden for checkForValidMove-metoden, som viser hvordan ImageView beveger seg.

    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) ; ) )

    Jeg håper denne artikkelen vil hjelpe deg når du utvikler dine egne prosjekter.

    
    Topp