Suchergebnisse in der URL beschreiben

JavaScriptBeginner
Jetzt üben

Einführung

Fieldnote ist ein kleiner Veranstaltungskalender fürs Wochenende. Ein nützlicher Suchlink sollte die Ansicht beschreiben: Suchbegriff, Kategorie, Sortierung und Ergebnisseite. Wer den Link öffnet, sollte dieselben Veranstaltungen sehen, einschließlich der richtigen Zeit und des richtigen Orts bei zwei gleichnamigen Veranstaltungen. Du baust diese Zustandsbeziehung rund um eine vorbereitete responsive Website und einen kleinen lokalen Katalog auf.

Vorausgesetzt werden grundlegende Terminalpfade, HTML-Formulare, CSS-Layout und Fokus sowie JavaScript-Arrays, Objekte, Funktionen, DOM-Auswahl und Ereignisse. Dieses Lab führt Array-Filterung, Vergleichsfunktionen, Seitengrenzen, URL und URLSearchParams ein. Suche und URL-Verarbeitung haben viele Anwendungen; hier entsteht eine vollständige, reproduzierbare Ansicht mit vier Werten. Der vorbereitete Renderer erstellt Karten aus den Datensätzen, die dein Code auswählt. Backend- oder Framework-Wissen ist nicht erforderlich. Alle Veranstaltungen sind synthetisch. Die 55 Minuten sind eine Autorenschätzung einschließlich Lesen und gewöhnlicher Fehler.

Verwende Workspace für Befehle und Fieldnote für die Einstiegsseite. Dieses Lab startet unabhängig. Bearbeite nur /home/labex/project/fieldnote/work/selection.js, state.js und url.js; app.js ist hier der vorbereitete Controller und wird im nächsten Lab zu deiner Aufgabe. Erhalte catalog.js, view.js, index.html, style.css, die separate Study-Ansicht und den vorbereiteten Dienst. Der Controller sendet bereits Formulare ab und zeichnet die Seite neu; mit replaceState aktualisiert er den aktuellen Eintrag. Der Browserverlauf ist hier vorbereitetes Verhalten und noch kein Lernziel. Die Website-Beschriftungen bleiben Englisch.

Datensätze in stabiler Reihenfolge auswählen

In diesem Schritt öffnest du eine funktionierende geteilte Ansicht und gibst deiner Arbeitsseite ein vorhersehbares Verhalten für Suchbegriff, Kategorie und Sortierung.

Wähle in Fieldnote den Link Open Study view in a new page. Dieser echte Link öffnet eine eigenständige Browserseite außerhalb des eingebetteten Produkt-Tabs. Führe die Website-Aktionen dort aus. Die Adresse enthält q, category, sort und page; der Suchbegriff ist print & fold, die Kategorie Make, und Page 2 of 2 zeigt Print & Fold: map edition und Print & Fold. Letzteres ist die Veranstaltung um 14:00 in North room, nicht die frühere gleichnamige Veranstaltung. Wähle unter den Ergebnissen Open this view in a new page. Die neue Seite muss dieselben Steuerelemente, Seite, Titel, Daten und Orte zeigen. Der Link funktioniert nur, solange dieses Lab und seine Proxyroute laufen. Dies ist ein unabhängiges Beispiel, weder deine Arbeit noch ein Prüfergebnis.

Die folgende unabhängige Study-Ansicht zeigt die zwei Datensätze der zweiten Seite. Vergleiche neben den Titeln auch Datum, Uhrzeit und Ort.

Unabhängige Study-Ansicht mit Datensätzen der zweiten Seite

Schließe die zusätzlichen Beispielseiten. Wähle auf der Fieldnote-Einstiegsseite Open Work view in a new page. Lass diese eigenständige Arbeitsseite offen. Wechsle zum Bearbeiten der Dateien zurück zum Produkt-Tab Workspace. Ein Tabwechsel ist etwas anderes als ein Website-Link oder die Back-Schaltfläche des Browsers. Deine Arbeit beginnt unvollständig, obwohl Study funktioniert.

cd wechselt das Verzeichnis dieses Terminals; ein absoluter Pfad beginnt mit /. pwd gibt das aktuelle Verzeichnis aus. cat zeigt eine kleine Textdatei, ohne sie zu verändern:

cd /home/labex/project/fieldnote/work
pwd
cat catalog.js

Lies drei Datensätze: FN-101 und FN-102 beginnen beide am 2026-11-14 um 10:00; FN-108 hat denselben Titel wie FN-102, aber ein späteres Datum. Die Eingabereihenfolge des Katalogs unterscheidet sich absichtlich von der Anzeige. Sage die ersten drei Treffer für print & fold, Kategorie make, nach frühestem Termin voraus: FN-101, FN-102, FN-104. Vergleiche die tatsächlichen Identitäten, nicht nur die Kartenanzahl.

Wir filtern, ohne den Katalog zu ändern. filter erzeugt ein neues Array passender Objekte. includes prüft eine wörtliche Teilzeichenfolge; toLowerCase macht die Suche unabhängig von Groß- und Kleinschreibung. Durchsuche die einzelne zusammengesetzte Zeichenfolge title + ' ' + description; ein Treffer darf das verbindende Leerzeichen überschreiten. && verlangt beide Bedingungen, || mindestens eine. all lässt jede Kategorie zu. Die Pfeilfunktion erhält jeweils eine Veranstaltung.

sort verändert das sortierte Array. Wenn du das neue gefilterte Array sortierst, bleibt der vorbereitete Katalog erhalten. Eine Vergleichsfunktion liefert eine negative Zahl, null oder eine positive Zahl. Die Hilfsfunktion unten nutzt die JavaScript-Zeichenfolgenvergleiche < und >. Die zeitliche Sortierung vergleicht date + 'T' + time und bei Gleichstand die ASCII-ID. Die Titelsortierung vergleicht kleingeschriebene Titel, dann die ID. Diese feste Textreihenfolge hängt weder von der Browsersprache noch von ursprünglichen Arraypositionen ab. Die vorbereiteten Daten liegen in derselben Zeitzone; du implementierst keine zeitzonenübergreifende Terminplanung.

Der bedingte Ausdruck condition ? first : second wählt einen Wert. primary || ... verwendet hier den ID-Vergleich nur, wenn das primäre Ergebnis null ist. CATALOG ist das vorbereitete Objekt, das vor deinen Dateien geladen wird. state enthält q, category, sort und page; der nächste Schritt macht diese Werte sicher und konsistent.

Speichere die vollständige Funktion in selection.js. cat > filename ersetzt diese Datei. Das in Anführungszeichen gesetzte <<'JS' beginnt ein Here-Dokument: Füge die Zeilen bis zum abschließenden JS allein in einer Zeile ein. Die Anführungszeichen erhalten JavaScript-Sonderzeichen unverändert. Dies ist Bearbeiten und Speichern im Terminal, keine Automatisierung des WebIDE-Editors.

cat > selection.js <<'JS'
function compare(a, b) {
  return a < b ? -1 : a > b ? 1 : 0;
}
function matches(state) {
  return CATALOG.events.filter(event =>
    (state.category === 'all' || event.category === state.category) &&
    (event.title + ' ' + event.description).toLowerCase()
      .includes(state.q.toLowerCase())
  ).sort((a, b) => {
    const primary = state.sort === 'title'
      ? compare(a.title.toLowerCase(), b.title.toLowerCase())
      : compare(a.date + 'T' + a.time, b.date + 'T' + b.time);
    return primary || compare(a.id, b.id);
  });
}
JS

Kehre zur eigenständigen Arbeitsseite zurück und lade neu. Warte auf Steuerelemente und Karten. Gib print & fold in Keyword ein, wähle Make unter Category, belasse Soonest first und aktiviere Search. Du solltest die drei vorhergesagten Datensätze sehen; die beiden Termine um 10:00 unterscheiden sich durch Titel und Orte. Ändere Sort by zu Title A–Z, sende erneut ab und erwarte Print & Fold, Print & Fold, Print & Fold: colour. Lies die Daten: Die gleichnamigen Veranstaltungen sind FN-102, dann FN-108. Nur eine Auswahl zu ändern bearbeitet einen Entwurf; Search bestätigt alle drei Filter gemeinsam. Die geteilte URL ist noch unvollständig.

Sind die Ergebnisse leer, prüfe zuerst Suchbegriff und Kategorie. Ein Tippfehler wie prnit hat berechtigterweise keine Treffer; ändere ihn zu print & fold und sende erneut ab. Reagiert die Seite nach einer Änderung nicht mehr, gehe zu Workspace, führe cat selection.js aus, vergleiche Klammern und Anführungszeichen mit dem vollständigen Block und ersetze die Datei erneut. Lade die Arbeitsseite nach dem Speichern neu; die VM muss nicht zurückgesetzt werden.

Führe Check dieses Schritts aus, nachdem du beide Sortierungen beobachtet hast. Die Prüfung führt deine ursprünglichen Frontend-Dateien in einer temporären Browser-Testumgebung aus und prüft vollständige Datensatzbeziehungen. Sie vervollständigt nicht die aktive Seite und zählt Study nicht als dein Ergebnis.

Filter und Seitengrenzen normalisieren

In diesem Schritt wandelst du Entwürfe oder eingehende Werte in einen vorhersehbaren Zustand um, auch bei leeren Ergebnissen und der letzten verfügbaren Seite.

Bleibe auf der eigenständigen Arbeitsseite. Sende print & fold, Make, Soonest first ab und wähle Next. Es gibt fünf Treffer und drei Plätze pro Seite; Seite 2 enthält deshalb die letzten zwei. Drei Datensätze pro Seite ist der vorbereitete Wert CATALOG.pageSize. Der Renderer verwendet slice(start, end), um eine Seite zu entnehmen, ohne die vollständige Liste zu verändern. Indizes beginnen bei null, das Ende ist ausgeschlossen: Seite 1 nutzt slice(0, 3), Seite 2 slice(3, 6). Jede Karte verwendet das gewählte Veranstaltungsobjekt samt eigener ID, Titel, Beschreibung, Datum, Uhrzeit und Ort.

Betrachte nun die eingehende Seite 999, eine unbekannte Kategorie oder einen Suchbegriff mit äußeren Leerzeichen. Die Normalisierung gibt diesen Werten vor dem Zeichnen eine öffentliche Bedeutung. Ein fehlender Suchbegriff wird leer; entferne nur Leerraum an seinen Enden und erhalte innere Leerzeichen und die Schreibweise des Benutzers. Die Suche ignoriert weiterhin Groß- und Kleinschreibung. Eine fehlende/unbekannte Kategorie wird all, eine fehlende/unbekannte Sortierung soon. Wandle die Seite mit Number um: Positive sichere Ganzzahlen sind erlaubt, einschließlich der gleichwertigen Schreibweise 2.0. Ungültige Werte, der Wert 0 sowie negative, nicht ganzzahlige oder unsichere Werte werden 1. Begrenze eine gültige zu große Seite auf die letzte Trefferseite. Null Treffer haben weiterhin Seite 1 von 1 und zwei deaktivierte Seitenschaltflächen.

Number.isSafeInteger vermeidet ungenau dargestellte Ganzzahlen. Math.ceil rundet auf: Fünf Treffer geteilt durch drei ergeben zwei Seiten. Math.max(1, ...) hält die Seitenanzahl leerer Ergebnisse auf eins; Math.min begrenzt die angeforderte Seite. Array.includes prüft auch die Zugehörigkeit zu erlaubten Kategorien und Sortierungen. Die Vorgaben mit || behandeln fehlende oder leere Eingaben. Ein normalisierter Zustand enthält Werte, keinen bereits codierten URL-Text.

Wechsle zu Workspace, weiterhin in /home/labex/project/fieldnote/work. Ersetze state.js durch diese vollständige Funktion:

cat > state.js <<'JS'
function normalize(raw) {
  const state = {
    q: (raw.q || '').trim(),
    category: CATALOG.categories.includes(raw.category) ? raw.category : 'all',
    sort: ['soon', 'title'].includes(raw.sort) ? raw.sort : 'soon',
    page: Number(raw.page || 1)
  };
  if (!Number.isSafeInteger(state.page) || state.page < 1) state.page = 1;
  const pages = Math.max(1, Math.ceil(matches(state).length / CATALOG.pageSize));
  state.page = Math.min(state.page, pages);
  return state;
}
JS

Sie ruft deine Funktion matches auf, um die Grenzen nach dem Filtern zu berechnen. Sie sortiert den ursprünglichen Katalog nicht. Sage den Zustand für q: ' print & fold ', category: 'make', sort: 'soon', page: '999' voraus: Suchbegriff ohne äußere Leerzeichen, Kategorie und Sortierung unverändert, Seite 2. Bei page: '2.5' ist es Seite 1. Eingehende URL-Werte probierst du im nächsten Schritt aus, sobald der Leser existiert.

Kehre zur Arbeitsseite zurück und lade neu. Gib in Keyword zwei Leerzeichen, dann print & fold und danach zwei Leerzeichen ein. Wähle Make und aktiviere Search. Danach sollte das Feld print & fold ohne äußere Leerzeichen enthalten. Wähle Next: Nur die Kartenedition und die Veranstaltung um 14:00 in North room bleiben übrig, und Next ist deaktiviert. Suche von Seite 2 aus nach sound + light, Listen, Title A–Z. Das bestätigt neue Filter und setzt auf Page 1 of 1 zurück. Das wörtliche Pluszeichen gehört zum Titel und ist kein Leerzeichen. Suche nach no such constellation: keine Karten, eine lesbare Meldung, Seite 1 von 1 und beide Schaltflächen deaktiviert. Das ist korrekt. Stelle passende Suchbegriffe und Kategorien wieder her und sende ab.

Bestätige vor Check, dass Katalog und gesamte Datensatzinhalte unverändert sind. Prüfungen unbekannter Werte und numerischer URL-Schreibweisen kommen im nächsten Schritt dazu; dieser prüft das normalisierte Formular und erreichbare Seitengrenzen.

Die tatsächliche Ansichts-URL lesen und schreiben

In diesem Schritt lässt du einen direkt geöffneten Link alle vier bestätigten Werte und ihre sichtbaren Datensätze wiederherstellen.

Eine URL besitzt Ursprung, Pfad, Abfrage und optional ein Fragment nach #. Der LabEx-Proxy liefert den echten Ursprung und Pfad. Rate keine neue Basis, indem du den Ursprung und / zusammensetzt. new URL(location.href) beginnt mit der tatsächlichen Adresse dieser Seite. searchParams liest decodierte Abfragewerte mit get und schreibt normale, nicht codierte Werte mit set. Trennzeichen wie das & im Suchbegriff werden codiert, ein wörtliches Plus als %2B. Leerzeichen können als + oder %20 serialisiert werden. Ein Aufruf von encodeURIComponent vor set würde doppelt codieren; übergib den ursprünglichen Wert.

Der Kurs verwaltet nur q, category, sort und page. Erhalte alle zusätzlichen Abfrageparameter und das vorhandene Fragment; sie gehören nicht zum Filterzustand und können der Plattform gehören. Fehlende oder Standardwerte dürfen entfallen oder ausdrücklich angegeben sein. Parameterreihenfolge, gleichwertige numerische Seiten und die zwei Leerzeichenschreibweisen ändern die Bedeutung nicht. Die Initialisierung darf eine URL normalisieren, ohne einen zusätzlichen Besuch anzulegen. In diesem Lab erledigt der vorbereitete Controller das Ersetzen; das nächste lehrt die Verlaufsaufrufe.

Die Schleife for...of durchläuft die vier bekannten Schlüsselzeichenfolgen. delete entfernt jeweils den alten verwalteten Abfragewert, bevor der Schreiber andere als Standardwerte setzt.

Speichere in Workspace Leser und Schreiber in url.js:

cat > url.js <<'JS'
function readURL() {
  const params = new URL(location.href).searchParams;
  return normalize({q: params.get('q'), category: params.get('category'),
    sort: params.get('sort'), page: params.get('page')});
}
function stateURL(state) {
  const url = new URL(location.href);
  for (const key of ['q', 'category', 'sort', 'page']) url.searchParams.delete(key);
  if (state.q) url.searchParams.set('q', state.q);
  if (state.category !== 'all') url.searchParams.set('category', state.category);
  if (state.sort !== 'soon') url.searchParams.set('sort', state.sort);
  if (state.page !== 1) url.searchParams.set('page', state.page);
  return url;
}
JS

Das vorherige Löschen entfernt alte Filter bei Auswahl eines Standardwerts und bewahrt unbekannte Schlüssel. Die bedingten Zeilen lassen nur unsere Standardwerte weg. Der Schreiber liefert ein URL-Objekt; selbst navigiert er nicht. Der vorbereitete Controller ändert die Adresse, bevor der Renderer das tatsächliche Freigabefeld und den Link aktualisiert.

Kehre zur Arbeitsseite zurück und lade neu. Suche nach print & fold, Make, Title A–Z und wähle Next. Lies das Freigabefeld: Es repräsentiert alle vier aktuellen Werte, einschließlich sort=title und page=2. Wähle Open this view in a new page und lade die neue Seite neu. Erwarte Print & Fold: map edition, dann Print & Fold: tiny type, die letzten beiden Datensätze der Titelsortierung. Prüfe ihre Daten und Orte, nicht nur ihre Anzahl. Das ist ein echter Link zu deinen Arbeitsdateien. Der unabhängige Check öffnet ihn auch in einem sauberen Browserkontext ohne alte lokale Voreinstellungen.

Verwende für diese eingehenden Tests die Adressleiste der eigenständigen Seite. Behalte Ursprung und /work/-Pfad bei; ersetze nur die Abfrage nach ?. Ergänze #directory-title, um die Fragmenterhaltung zu testen. Beginne mit dieser Abfrage:

?edition=november&platform=keep-me&q=print%20%26%20fold&category=make&sort=soon&page=999#directory-title

Sie muss die Kartenedition und das Ereignis in North room auf Seite 2 zeigen, mit Soonest first ausgewählt. Die normalisierte Adresse darf sort=soon weglassen oder + für Leerzeichen nutzen; edition, platform und Fragment bleiben erhalten. Ersetze die Abfrage nun durch:

?edition=november&category=unknown&sort=unknown&page=2.5#directory-title

Erwarte einen leeren Suchbegriff, All categories, Soonest first, Page 1 of 4 und die Datensätze FN-101, FN-102, FN-105. Ein unbekannter Wert erhält den Standardwert und ist kein Grund zum Zurücksetzen. Eine Abfrage mit page=2.0 und Suchbegriff/Kategorie des ersten Tests bedeutet ebenfalls Seite 2. Reihenfolge und Standardschreibweise sind flexibel, der genaue sichtbare Zustand und die vollständigen Datensätze nicht.

Behalte die eigenständige Arbeitsseite zum Lesen. Bei etwa 768 und danach 390 Pixeln müssen Filter, Seitenschaltflächen, Freigabelink und vollständige Texte ohne horizontales Scrollen nutzbar bleiben. Drücke Tab, um den sichtbaren Fokus zu beobachten. Seitenaufbau und Stile sind vorbereitet; bewahre sie. Führe Check aus. Dieses Lab prüft direkte URL-Wiederherstellung, die Übereinstimmung von URL/Steuerelementen/Ergebnissen und sichere Grenzen. Back/Forward wird noch nicht verlangt: Der vorbereitete Controller ersetzt den aktuellen Eintrag und bildet den Ausgangspunkt des nächsten Labs.

Zusammenfassung

Du hast vollständige Veranstaltungsdatensätze mit stabilem Auflösen von Gleichständen ausgewählt, Filter und Seitengrenzen normalisiert und vier Werte in der echten Ansichts-URL gelesen und geschrieben. Gleichwertige URL-Schreibweisen ergeben dieselbe Ansicht unabhängig von der ursprünglichen Katalogreihenfolge. Das nächste Lab ersetzt den vorbereiteten Controller, damit auch echtes Back und Forward diese Ansichten wiederherstellen.