How do I change a page in jQuery Mobile?

Sådan Skifter og Scripting af Sider i jQuery Mobile

05/10/2025

Rating: 4.69 (3978 votes)

jQuery Mobile, et robust framework til udvikling af mobilvenlige webapplikationer, adskiller sig markant fra traditionel webudvikling, primært på grund af dets Ajax-drevne navigationssystem. Dette system genindlæser ikke hele siden ved hvert linkklik, men indlæser i stedet kun indholdet af det nye “side”-element ind i den eksisterende DOM. Denne tilgang skaber en mere flydende og app-lignende brugeroplevelse, men den kræver også en specifik forståelse for, hvordan man skifter sider programmatisk og hvordan man udfører JavaScript-kode, der påvirker dynamisk indlæste elementer. Uanset om du er en erfaren udvikler, der dykker ned i jQuery Mobile, eller en nybegynder, der ønsker at mestre mobilwebudvikling, er det afgørende at forstå disse mekanismer for at bygge responsive og effektive applikationer.

How to execute code when a new page is created in jQuery Mobile?
To execute code whenever a new page is loaded and created in jQuery Mobile, you can bind to the pageinit event. The pageinit event is triggered on a page when it is initialized, right after initialization occurs. Most of jQuery Mobile's official widgets auto-initialize themselves based on this event, and you can set up your code to do the same.
Indholdsfortegnelse

Skift Sider Effektivt med $.mobile.changePage()

Hvis du ønsker at ændre den aktuelle aktive side ved hjælp af JavaScript, er den primære metode at bruge $.mobile.changePage(). Denne funktion giver dig fuld kontrol over sideovergange og indlæsningsadfærd. Den kan bruges til at navigere til både interne sider (dem der allerede er i DOM'en) og eksterne sider (dem der skal indlæses via Ajax).

Her er et par enkle eksempler på, hvordan du kan bruge changePage:

// Overgang til siden "om-os.html" med en 'slideup' overgang $.mobile.changePage( "om-os.html", { transition: "slideup"} ); // Overgang til siden "soegeresultater.php" ved hjælp af data fra en formular med id'et "soeg" $.mobile.changePage( "soegeresultater.php", { type: "post", data: $("form#soeg").serialize() });

changePage()-metoden understøtter en række indstillinger (options), der giver dig finjusteret kontrol over navigationen. Disse indstillinger kan tilpasses for at opnå den ønskede brugeroplevelse og ydeevne.

Vigtige Indstillinger for changePage()

For at give dig et bedre overblik over de tilgængelige indstillinger for changePage(), har vi samlet de mest relevante i nedenstående tabel:

EgenskabStandardværdiTypeBeskrivelse
allowSamePageTransitionfalseBooleanTillader sideovergang til den aktuelle aktive side. Normalt ignoreres anmodninger om at skifte til den side, man allerede er på.
changeHashtrueBooleanAfgør, om hash'en i adresselinjen skal opdateres, hvilket skaber en ny browserhistorikpost. Hvis false, erstatter den nye side den aktuelle i browserhistorikken.
dataundefinedObject eller StringData, der skal sendes med en Ajax-sideanmodning. Anvendes kun, når 'to'-argumentet er en URL.
dataUrlundefinedStringDen URL, der skal bruges ved opdatering af browserplaceringen efter changePage er fuldført.
pageContainer$.mobile.pageContainerjQuery-samlingAngiver det element, der skal indeholde siden.
reloadPagefalseBooleanTvinger en genindlæsning af en side, selvom den allerede er i DOM'en. Anvendes kun, når 'to'-argumentet er en URL.
reversefalseBooleanAfgør, hvilken retning overgangen skal køre, når siden vises.
roleundefinedStringDen data-role værdi, der skal bruges ved visning af siden. Standard er undefined, hvilket betyder, at den stoler på værdien af @data-role-attributten på elementet.
showLoadMsgtrueBooleanAfgør, om indlæsningsbeskeden skal vises ved indlæsning af eksterne sider.
transition$.mobile.defaultPageTransitionStringDen overgang, der skal bruges, når siden vises.

Håndtering af Scripting og Hændelser i jQuery Mobile

Da jQuery Mobile anvender et Ajax-drevet navigationssystem, er der nogle vigtige overvejelser, når du skriver scripts, der manipulerer dit indhold. Den traditionelle $(document).ready()-funktion, som mange jQuery-udviklere kender, udløses kun én gang, når den første side indlæses. I en jQuery Mobile-applikation, hvor sider indlæses dynamisk i den samme DOM, er dette ikke tilstrækkeligt for at udføre kode, når nye sider vises.

pageinit – Din Nye DOM Ready

For at udføre kode, hver gang en ny side indlæses og oprettes i jQuery Mobile, skal du binde til pageinit-hændelsen. Denne hændelse udløses på en side, lige efter den er initialiseret. De fleste af jQuery Mobile's officielle widgets auto-initialiserer sig selv baseret på denne hændelse, og du kan indstille din egen kode til at gøre det samme. Dette sikrer, at din kode kører, uanset om siden indlæses direkte via HTTP eller trækkes ind og vises via Ajax.

$( document ).delegate("#omSide", "pageinit", function() { alert('En side med id="omSide" blev netop oprettet af jQuery Mobile!'); });

Hvis du ønsker at manipulere en sides indhold, førpageinit-hændelsen udløses, og widgets auto-initialiseres, kan du i stedet binde til pagebeforecreate-hændelsen:

$( document ).delegate("#omSide", "pagebeforecreate", function() { alert('En side med id="omSide" er ved at blive oprettet af jQuery Mobile!'); });

Vigtig note: pageCreate() vs pageInit()Før Beta 2 af jQuery Mobile blev brugere anbefalet at binde til pagecreate-hændelsen for at manipulere jQuery Mobile-forbedret markup. I Beta 2 blev der foretaget en intern ændring, der afkoblede hver af widgets ved at binde til pagecreate-hændelsen i stedet for direkte kald til widget-metoderne. Som et resultat ville brugere, der bandt til pagecreate i mobileinit, opleve, at deres binding blev udført, før markup var blevet forbedret af plugins. I overensstemmelse med livscyklussen for jQuery UI Widget Factory, kaldes initialiseringsmetoden efter create-metoden, så pageinit-hændelsen giver den korrekte timing for post-forbedring manipulation af DOM og/eller JavaScript-objekter. Kort sagt, hvis du tidligere brugte pagecreate til at manipulere den forbedrede markup, før siden blev vist, er det meget sandsynligt, at du vil migrere til pageinit.

Scripts og Styles i Head vs. Body

Når en bruger klikker på et link på et jQuery Mobile-drevet websted, er navigationssystemets standardadfærd at bruge linkets href til at formulere en Ajax-anmodning (i stedet for at tillade browserens standard linkadfærd med fuld sideindlæsning). Når denne Ajax-anmodning sendes ud, modtager frameworket hele tekstindholdet, men det vil kun injicere indholdet af svar-body-elementet (eller mere specifikt data-role="page"-elementet, hvis det er angivet), hvilket betyder, at intet i sidens <head> vil blive brugt (med undtagelse af sidetitlen, som hentes specifikt).

Dette betyder, at scripts og styles, der refereres i en sides <head>, ikke vil have nogen effekt, når en side indlæses via Ajax, men de vil udføres, hvis siden anmodes normalt via HTTP. Når du scripter jQuery Mobile-websteder, skal begge scenarier overvejes. Årsagen til, at en sides <head> ignoreres, når den anmodes via Ajax, er, at potentialet for at genudføre den samme JavaScript er meget højt (det er almindeligt at referere de samme scripts på hver side af et websted). På grund af kompleksiteten ved at forsøge at omgå dette problem, overlader vi opgaven med at udføre side-specifikke scripts til udvikleren og antager, at head-scripts kun forventes at udføres én gang pr. browsersession.

Den enkleste tilgang, når man bygger et jQuery Mobile-websted, er at referere det samme sæt stylesheets og scripts i <head> på hver side. Hvis du har brug for at indlæse specifikke scripts eller styles til en bestemt side, anbefaler vi at binde logik til pageinit-hændelsen for at køre nødvendig kode, når en specifik side oprettes (som kan bestemmes af dens id-attribut eller på en række andre måder). Ved at følge denne tilgang sikres det, at koden udføres, hvis siden indlæses direkte eller trækkes ind og vises via Ajax.

En anden tilgang til side-specifik scripting ville være at inkludere scripts i slutningen af <body>-elementet, når der ikke er defineret et data-role=page-element, eller inde i det første data-role=page-element. Hvis du inkluderer dine brugerdefinerede scripts på denne måde, skal du være opmærksom på, at disse scripts udføres, når siden indlæses via Ajax eller almindelig HTTP, så hvis disse scripts er de samme på hver side, vil du sandsynligvis støde på problemer. Hvis du inkluderer scripts på denne måde, anbefaler vi at omslutte dit sideindhold i et data-role="page"-element og placere scripts, der refereres på hver side, uden for dette element. Scripts, der er unikke for denne side, kan placeres i dette element for at sikre, at de udføres, når siden hentes via Ajax.

Indlæsning af Eksterne Sider med $.mobile.loadPage()

Udover at skifte til eksisterende eller eksterne sider kan du også indlæse en ekstern side, forbedre dens indhold og indsætte den i DOM'en uden nødvendigvis at navigere til den med det samme. Dette gøres med metoden $.mobile.loadPage(). Dette kan være nyttigt, hvis du ønsker at forhåndsindlæse sider i baggrunden for at forbedre ydeevnen, når brugeren senere navigerer til dem.

Her er et simpelt eksempel på, hvordan du indlæser en side:

// Indlæs "om-os.html"-siden i DOM'en $.mobile.loadPage( "om-os.html" );

Ligesom changePage() understøtter loadPage() også en række indstillinger, der giver dig kontrol over indlæsningsprocessen, herunder data, dataUrl, pageContainer, reloadPage og showLoadMsg, som fungerer på samme måde som beskrevet for changePage().

Forbedring af Nyt Markup

jQuery Mobile er designet til automatisk at forbedre (style og tilføje funktionalitet til) standard HTML-elementer baseret på deres data-role-attributter. Denne auto-initialisering sker typisk, når en side indlæses og pageinit-hændelsen udløses. Men hvad sker der, når du genererer nyt HTML-markup via klient-side JavaScript, f.eks. ved at hente indhold via Ajax og indsætte det i DOM'en? Disse nye elementer vil ikke automatisk blive forbedret.

trigger("create") for Dynamisk Indhold

Hvis du genererer nyt markup klient-side eller indlæser indhold via Ajax og injicerer det i en side, kan du udløse create-hændelsen for at håndtere auto-initialiseringen for alle de plugins, der er indeholdt i det nye markup. Dette kan udløses på ethvert element (selv selve side-div'en), hvilket sparer dig for opgaven med manuelt at initialisere hvert plugin (listview, button, select osv.).

For eksempel, hvis en blok HTML-markup (sig en login-formular) blev indlæst via Ajax, udløs create-hændelsen for automatisk at transformere alle de widgets, den indeholder (inputfelter og knapper i dette tilfælde), til de forbedrede versioner. Koden for dette scenarie ville være:

$( ...nyt markup, der indeholder widgets... ).appendTo( ".ui-page" ).trigger( "create" );

create vs. refresh – En Vigtig Forskel

Det er vigtigt at skelne mellem create-hændelsen og refresh-metoden, som nogle widgets har. De tjener forskellige formål:

Metode/HændelseFormålAnvendelse
trigger("create")Forbedrer råt, nyt markup, der indeholder en eller flere widgets. Konverterer standard HTML til jQuery Mobile-styled widgets.Anvendes på en forælder eller det nye markup, der indeholder uforbedrede widgets. Udløses for at initialisere widgets, der endnu ikke er blevet behandlet af jQuery Mobile.
refresh()Opdaterer udseendet af eksisterende, allerede forbedrede widgets efter programmatiske ændringer.Anvendes direkte på en specifik widget-instans (f.eks. en listview, slider, selectmenu), når dens underliggende data eller struktur er ændret programmatisk, og UI'en skal afspejle disse ændringer.

For eksempel, hvis du havde en side, hvor du dynamisk tilføjede en ny uordnet liste med data-role=listview-attributten efter sideoprettelse, ville udløsning af create på et forælderelement af den liste transformere den til en listview-stylet widget. Hvis der derefter blev tilføjet flere listeelementer programmatisk, ville kald af listview'ens refresh-metode opdatere netop disse nye listeelementer til den forbedrede tilstand og lade de eksisterende listeelementer urørte.

Kontrol over Forbedring og Navigation

I visse situationer ønsker du måske at forhindre jQuery Mobile i automatisk at forbedre bestemte dele af dit markup eller at deaktivere Ajax-navigation for specifikke links eller formularer. jQuery Mobile tilbyder attributter og indstillinger til at håndtere disse scenarier.

data-enhance="false"-attributten

Fra jQuery Mobile 1.0 scannes alt markup inden for en side for elementer, der skal forbedres. Dette kan være problematisk for tredjeparts-widgets/biblioteker, der ikke ønsker, at nogen forbedrer deres markup eller tilknytter adfærd. For disse situationer kan du placere data-enhance="false"-attributten på et containerelement for at fortælle frameworket, at det ikke skal forbedre noget inde i det. Det er vigtigt at bemærke, at på grund af ydeevnepåvirkningen ved at finde et forælderelement med data-enhance="false"-attributten, skal denne funktion slås eksplicit til med $.mobile.ignoreContentEnabled=true.

data-ajax="false" Fungerer Nu på Containere

jQuery Mobile har altid tilbudt muligheden for at deaktivere Ajax-navigationssystemet fra at kapre et link eller en formularindsendelse via data-ajax="false"-attributten. Men der har været et behov for at anvende denne udelukkelse mere effektivt på en gruppering af links. I version 1.1 blev dette muligt ved simpelthen at tilføje data-ajax="false"-attributten til en forældrecontainer, og det vil udelukke alle underliggende links eller formularer fra Ajax-navigationssystemets adfærd. Ligesom med data-enhance="false", skal $.mobile.ignoreContentEnabled=true indstilles for at aktivere denne funktion.

Rulning til Specifikke Positioner Inden for en Side

Da jQuery Mobile bruger URL-hash'en til at bevare "Tilbage"-knap-adfærd, understøttes brug af sideankre til at springe ned til en position på siden ikke ved at bruge det traditionelle ankerlink (#foo). I stedet skal du bruge silentScroll-metoden til at rulle til en bestemt Y-position uden at udløse scroll-event-lyttere. Du kan sende et yPos-argument for at rulle til den pågældende Y-placering.

// Rul til Y 300px $.mobile.silentScroll(300);

Dette er især nyttigt for at opretholde brugerens scroll-position, når de navigerer frem og tilbage, eller for at føre dem til en specifik del af en længere side.

Binding til Mus- og Touch-hændelser (Virtuelle Hændelser)

En vigtig overvejelse i mobiludvikling er håndtering af mus- og touch-hændelser. Disse hændelser adskiller sig markant på tværs af mobile platforme. Selvom klikhændelser fungerer overalt, sker det typisk efter en betydelig forsinkelse på 500-700 ms. Denne forsinkelse er nødvendig for, at browseren kan vente på potentielle dobbelt-tap, scroll og udvidede hold-tap-hændelser.

For at undgå denne forsinkelse er det muligt at binde til touch-hændelser (f.eks. touchstart), men problemet med denne tilgang er, at nogle mobile platforme (som Windows Phone 7, BlackBerry) ikke understøtter touch. For at komplicere dette problem yderligere, vil nogle platforme udsende både touch- og mus-hændelser, så hvis du binder til begge typer, vil du opleve, at du får duplikerede hændelser for en enkelt interaktion.

jQuery Mobile's løsning er at skabe et sæt virtuelle hændelser, der normaliserer mus- og touch-hændelser. Dette giver udvikleren mulighed for at registrere lyttere for de grundlæggende mus-hændelser, såsom mousedown, mousemove, mouseup og click, og plugin'et vil tage sig af at registrere de korrekte lyttere bag kulisserne for at kalde lytteren på det hurtigst mulige tidspunkt for den pågældende enhed. Dette bevarer stadig rækkefølgen af hændelsesudløsning i det traditionelle musemiljø, hvis flere håndterere er registreret på det samme element for forskellige hændelser. Det virtuelle muse-system eksponerer følgende virtuelle hændelser til jQuery-bind-metoder:

  • vmouseover
  • vmousedown
  • vmousemove
  • vmouseup
  • vclick
  • vmousecancel

Ved at bruge disse virtuelle hændelser kan du sikre en konsistent og responsiv oplevelse på tværs af forskellige mobile enheder, uden at bekymre dig om de underliggende hændelsesforskelle.

Overførsel af Parametre Mellem Sider

En almindelig udfordring i webudvikling er at overføre data eller parametre mellem sider. I jQuery Mobile's standardopsætning understøtter frameworket ikke overførsel af query-parametre til interne/indlejrede sider. For eksempel, hvis frameworket ser et link til "#minSide?minId=1", fortolker det det som "#minSide" og navigerer til den interne side-div med et id på "minSide" og anvender en data-url af "#minSide?minId=1" til denne sidecontainer. Efterfølgende kald til andre parametre som "#minSide?minId=2" vil finde den samme div, fordi jQuery Mobile refererer til data-url på div'en, som kun sættes én gang og vil forblive "#minSide?minId=1".

Dette betyder, at du ikke kan bruge standard URL query-parametre (som ?id=123) til at sende data direkte til interne jQuery Mobile-sider på samme måde, som du ville gøre i en traditionel webapplikation. Hvis du har brug for at overføre parametre mellem sider i jQuery Mobile, er der dog løsninger tilgængelige:

  • Plugins: Der findes to populære plugins, som kan tilføjes dit projekt, hvis query-parametre er nødvendige mellem sider. Der er et letvægts page params plugin (uddybes ikke her, da det kræver ekstern viden) og et mere fuldt udstyret jQuery Mobile router plugin til brug med Backbone.js eller Spine.js (uddybes ikke her). Disse plugins giver dig de nødvendige værktøjer til at håndtere parametre på en mere robust måde.
  • Global JavaScript-objekt: En simpel, men mindre elegant løsning for små datasæt, er at gemme data i et globalt JavaScript-objekt, som kan tilgås af den modtagende side. Dette bør dog bruges med forsigtighed for at undgå at forurene det globale navnerum.
  • HTML5 Local Storage/Session Storage: For mere vedvarende data, eller data der skal overleve en browser-session, kan du bruge localStorage eller sessionStorage til at gemme og hente parametre.

Ofte Stillede Spørgsmål (FAQ)

Hvad er den vigtigste forskel mellem $(document).ready() og pageinit i jQuery Mobile?

Den vigtigste forskel er, at $(document).ready() kun udløses én gang, når den indledende DOM er klar, typisk ved den første sideindlæsning. I jQuery Mobile, da nye sider indlæses via Ajax og indsættes i den eksisterende DOM, udløses $(document).ready() ikke for disse efterfølgende sider. pageinit-hændelsen er derimod designet til at udløses, hver gang et nyt data-role="page"-element er initialiseret, uanset om det er den første side eller en side, der er indlæst via Ajax. Derfor bør du bruge pageinit til at initialisere din side-specifikke JavaScript-kode i jQuery Mobile.

Hvorfor virker mine CSS-filer ikke, når jeg navigerer via Ajax?

Når jQuery Mobile indlæser sider via Ajax, injicerer det kun indholdet af <body>-elementet (eller mere specifikt data-role="page"-elementet) fra den hentede side ind i den aktuelle DOM. Indholdet af den hentede sides <head>-sektion, hvor CSS-filer typisk er linket, ignoreres. Dette forhindrer genindlæsning af de samme scripts og styles. For at sikre, at dine styles anvendes korrekt, skal du enten inkludere alle dine globale CSS-filer i <head> på din hovedside (den første side, der indlæses) og på alle andre sider, eller du skal dynamisk indlæse side-specifik CSS ved hjælp af JavaScript, hvis det er absolut nødvendigt for en bestemt side.

Hvordan forhindrer jeg jQuery Mobile i at style et bestemt element?

Du kan forhindre jQuery Mobile i automatisk at forbedre et element og dets underordnede elementer ved at tilføje attributten data-enhance="false" til container-elementet. Husk, at du skal aktivere denne funktion globalt ved at sætte $.mobile.ignoreContentEnabled = true; i din JavaScript-kode, før jQuery Mobile initialiseres (f.eks. i en mobileinit-hændelse).

Kan jeg bruge traditionelle URL-parametre (f.eks. ?id=123) til at sende data mellem interne jQuery Mobile-sider?

Nej, jQuery Mobile understøtter ikke direkte overførsel af traditionelle URL query-parametre til interne sider. Frameworket ignorerer query-delen af URL'en, når det matcher en hash til et data-role="page"-element i DOM'en. For at overføre data mellem sider anbefales det at bruge alternative metoder såsom HTML5 localStorage eller sessionStorage, et globalt JavaScript-objekt (til simple tilfælde), eller et af de dedikerede jQuery Mobile plugins som “page params plugin” eller “jQuery Mobile router”.

Hvad er formålet med jQuery Mobile's virtuelle muse- og touch-hændelser?

Formålet med virtuelle hændelser (f.eks. vclick, vmousedown) er at normalisere og optimere håndteringen af muse- og touch-interaktioner på tværs af forskellige mobile enheder. De løser problemer som den indbyggede 300ms forsinkelse på klikhændelser på mange mobile browsere og håndterer forskelle i, hvordan touch- og musehændelser udløses på forskellige platforme. Ved at bruge virtuelle hændelser sikrer du, at din applikation reagerer hurtigt og konsekvent på brugerinput, uanset enhedstype.

Afsluttende Bemærkninger

At mestre sideovergange og scripting i jQuery Mobile handler om at forstå frameworkets Ajax-drevne arkitektur. Ved at udnytte $.mobile.changePage() med dets mange indstillinger, binde til pageinit-hændelsen for dynamisk indhold, og forstå brugen af trigger("create") for nyt markup, kan du bygge robuste, responsive og brugervenlige mobilwebapplikationer. Selvom nogle aspekter, som parameteroverførsel, kræver alternative tilgange, tilbyder jQuery Mobile de nødvendige værktøjer og fleksibilitet til at overvinde disse udfordringer og levere en fremragende mobiloplevelse. En dybdegående forståelse af disse koncepter vil give dig mulighed for at udvikle applikationer, der føles lige så native som de er webbaserede.

Hvis du vil læse andre artikler, der ligner Sådan Skifter og Scripting af Sider i jQuery Mobile, kan du besøge kategorien Teknologi.

Go up