Einleitung

Der Aufbau einer dynamischen Fotogalerie mit Filter- und Sortierfunktionen verwandelt eine statische Bildsammlung in eine ansprechende, benutzerfreundliche Erfahrung. Besucher können schnell Bilder finden, die ihren Interessen entsprechen - zum Beispiel Filtern nach Natur, Stadt oder Menschen - und die Ergebnisse nach Name, Datum oder Bewertung ohne erneutes Laden einer Seite neu ordnen. Dieser Artikel bietet einen umfassenden, produktionsbereiten Ansatz zur Erstellung einer solchen Galerie mit einfachem JavaScript, HTML und CSS. Sie lernen, wie Sie Ihr Markup strukturieren, eine effiziente Filter- und Sortierlogik anwenden, die Leistung mit faulem Laden verbessern und die besten Praktiken für die Zugänglichkeit befolgen. Die endgültige Galerie wird ansprechend, wartbar und leicht erweiterbar sein.

Einrichten der HTML-Struktur

Eine gut strukturierte HTML-Grundlage macht das Filtern und Sortieren einfach. Jedes Bildelement sollte benutzerdefinierte -Attribute tragen, die seine Kategorie, seinen Namen, sein Datum oder jede andere Eigenschaft beschreiben, nach der Sie filtern oder sortieren möchten.

Basis-Markup für Filter und Sortiersteuerungen

Erstellen Sie einen Container für Filtertasten und einen anderen für Sortiersteuerungen.

<div id="controls">
 <div id="filter-buttons" role="group" aria-label="Filter photos by category">
 <button data-filter="all" class="active">Show All</button>
 <button data-filter="nature">Nature</button>
 <button data-filter="city">City</button>
 <button data-filter="people">People</button>
 </div>
 <div id="sort-options" role="group" aria-label="Sort photos">
 <button data-sort="name">Sort by Name</button>
 <button data-sort="date">Sort by Date</button>
 <button data-sort="rating">Sort by Rating</button>
 </div>
</div>

Einschließlich und verbessert die Zugänglichkeit für Bildschirmleser. Die -Taste ist mit einer Klasse markiert, um den Anfangszustand anzuzeigen; Sie werden dies mit CSS stylen.

Bildgalerie Container

Legen Sie innerhalb eines jedes Foto in ein eigenes Wrapper-Element, verwenden Sie , , und Attribute zum Filtern und Sortieren.

<div id="gallery" class="photo-grid">
 <div class="photo" data-category="nature" data-name="Sunset Over the Hills" data-date="2023-06-15" data-rating="4.5">
 <img src="images/sunset.jpg" alt="Sunset over rolling hills" loading="lazy">
 <div class="photo-caption">Sunset Over the Hills</div>
 </div>
 <div class="photo" data-category="city" data-name="Downtown Skyline" data-date="2023-07-01" data-rating="4.2">
 <img src="images/skyline.jpg" alt="Downtown skyline at dusk" loading="lazy">
 <div class="photo-caption">Downtown Skyline</div>
 </div>
 <!-- more photos -->
</div>

Das -Attribut verzögert das Laden von Off-Screen-Bildern und verbessert die anfängliche Ladeleistung der Seite. Jeder Foto-Wrapper kann auch eine Beschriftung oder ein Overlay für zusätzliche Informationen enthalten.

Datenattribute effektiv nutzen

Datenattribute (z. B. , ) sind nicht auf Strings beschränkt. Für numerische Sortierung speichern Sie Zahlen als Strings; JavaScript wird sie nach Bedarf analysieren. Für mehrere Kategorien können Sie eine raumgetrennte Liste wie speichern und während der Filterung aufteilen. Diese Technik ermöglicht es, Bilder unter mehreren Filtern zu sehen, eine Funktion, die wir später implementieren werden. Für einen umfassenden Verweis auf Datenattribute siehe MDN-Dokumentation auf der Dataset-API.

Styling der Galerie mit CSS

Ein sauberes, responsives Layout stellt die Bühne für die interaktiven Funktionen bereit. Verwenden Sie CSS-Grid oder Flexbox für das Raster von Fotos und stylen Sie die Schaltflächen, um aktive Filter und den Sortierzustand anzuzeigen.

Fotogitter-Layout

.photo-grid {
 display: grid;
 grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
 gap: 1rem;
 padding: 1rem 0;
}

.photo {
 position: relative;
 overflow: hidden;
 border-radius: 8px;
 box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.photo img {
 width: 100%;
 height: auto;
 display: block;
 transition: transform 0.3s ease;
}

.photo:hover img {
 transform: scale(1.05);
}

Dieses Raster sorgt dafür, dass sich Bilder an die Bildschirmgröße anpassen. Der Hover-Effekt fügt eine subtile Zoom-Interaktion hinzu, wodurch sich die Galerie polierter anfühlt.

Aktiver Zustand für Tasten

#filter-buttons button.active,
#sort-options button.active {
 background-color: #007acc;
 color: #fff;
 border-color: #007acc;
}

button {
 padding: 0.5rem 1rem;
 border: 1px solid #ccc;
 background: #fff;
 cursor: pointer;
 margin: 0.25rem;
 border-radius: 4px;
 transition: background 0.2s, color 0.2s;
}

button:hover {
 background: #e6e6e6;
}

Durch das Anwenden der -Klasse auf die aktuelle Filter-/Sortier-Taste wird visuelles Feedback gegeben. JavaScript verwaltet das Hinzufügen und Entfernen dieser Klasse.

Responsive Überlegungen

Stellen Sie sicher, dass die Galerie auf Touch-Geräten funktioniert. Erhöhen Sie die Zielgrößen der Tasten auf mindestens 44px mal 44px (Empfehlung WCAG 2.1). Verwenden Sie Medienabfragen, um bei Bedarf von einem mehrspaltigen Raster auf eine einzelne Spalte auf sehr kleinen Bildschirmen zu wechseln.

JavaScript Filterung implementieren

Jetzt erwecken wir die Galerie zum Leben. Die Kernidee: Hören Sie auf Klicks auf Filter-Buttons, zeigen oder verstecken Sie dann Fotoelemente basierend auf ihrem -Attribut.

DOM-Elemente auswählen und initialisieren

const filterButtons = document.querySelectorAll('#filter-buttons button');
const sortButtons = document.querySelectorAll('#sort-options button');
const gallery = document.getElementById('gallery');
let photos = Array.from(gallery.children);
let activeFilter = 'all';
let activeSort = 'name'; // default sort

Die Speicherung von als Array ermöglicht uns einen einfachen Zugriff auf Array-Methoden wie und Wir verfolgen auch die aktuelle Filter- und Sortierreihenfolge, damit wir die Sortierung nach einem Filterwechsel erneut anwenden können.

Filterlogik

function filterPhotos(filter) {
 activeFilter = filter;
 photos.forEach(photo => {
 const categories = photo.dataset.category; // may be a space-separated string
 const shouldShow = filter === 'all' || categories.split(' ').includes(filter);
 photo.style.display = shouldShow ? '' : 'none';
 });
 // After filtering, re-sort the visible photos
 sortPhotos(activeSort);
}

Diese Funktion unterstützt mehrere Kategorien: Wenn , dann wird das Foto entweder mit “Natur” oder “Landschaft” angezeigt. Hinweis: gibt den Wert von zurück (als Zeichenfolge).

Anbringen von Event-Hörern an Filter-Tasten

filterButtons.forEach(button => {
 button.addEventListener('click', () => {
 const filter = button.dataset.filter;
 // Update active class on filter buttons
 filterButtons.forEach(btn => btn.classList.remove('active'));
 button.classList.add('active');
 // Apply filter
 filterPhotos(filter);
 });
});

Das Entfernen der Klasse von allen Buttons und das Hinzufügen zu der angeklickten sorgt für visuelle Konsistenz. Die Funktion wird mit dem ausgewählten Filterwert aufgerufen.

JavaScript Sorting implementieren

Sortieren reorganisiert die sichtbaren Fotos im DOM basierend auf einem ausgewählten Attribut (z. B. Name, Datum, Bewertung).

Sortierfunktion

function sortPhotos(sortBy) {
 activeSort = sortBy;
 // Get currently visible photos (display not 'none')
 const visiblePhotos = photos.filter(photo => photo.style.display !== 'none');

 visiblePhotos.sort((a, b) => {
 let valA, valB;
 switch (sortBy) {
 case 'name':
 valA = a.dataset.name.toLowerCase();
 valB = b.dataset.name.toLowerCase();
 return valA.localeCompare(valB);
 case 'date':
 valA = new Date(a.dataset.date);
 valB = new Date(b.dataset.date);
 return valA - valB;
 case 'rating':
 valA = parseFloat(a.dataset.rating);
 valB = parseFloat(b.dataset.rating);
 return valB - valA; // descending: highest first
 default:
 return 0;
 }
 });

 // Re‑append sorted photos back to the gallery container
 visiblePhotos.forEach(photo => gallery.appendChild(photo));
}

Sortieren funktioniert nur bei sichtbaren Fotos, was bedeutet, dass Sie nach einem Filterwechsel die Reihenfolge nach der aktiven Sortierung wiederherstellen. Für Strings verwenden wir für die richtige alphabetische Reihenfolge. Dates werden als Date-Objekte verglichen und Ratings werden in absteigender Reihenfolge sortiert (am beliebtesten zuerst).

Event-Hörer für Sort Buttons

sortButtons.forEach(button => {
 button.addEventListener('click', () => {
 const sortBy = button.dataset.sort;
 sortButtons.forEach(btn => btn.classList.remove('active'));
 button.classList.add('active');
 sortPhotos(sortBy);
 });
});

Wenn auf eine Sortiertaste geklickt wird, aktualisieren wir die aktive Klasse und rufen mit der gewünschten Sortiertaste auf. Da bereits nach dem Filtern aufruft, bleibt die Galerie konsistent.

Ersteinrichtung

// Set default active buttons
document.querySelector('#filter-buttons [data-filter="all"]').classList.add('active');
document.querySelector('#sort-options [data-sort="name"]').classList.add('active');

// Load and initially sort by name
filterPhotos('all');

Durch Aufrufen von wird sichergestellt, dass die Galerie mit allen Bildern gefüllt und nach der Standardsortierung (Name) sortiert wird.

Ein einfacher Kategoriefilter ist nützlich, aber Sie können mehrere Filter kombinieren oder eine Textsucheingabe hinzufügen.

Mehrere Kategoriefilter (Checkboxen)

Verwenden Sie anstelle von exklusiven Schaltflächen Kontrollkästchen, damit Benutzer mehrere Kategorien auswählen können:

<div id="filter-checkboxes">
 <label><input type="checkbox" value="nature" checked> Nature</label>
 <label><input type="checkbox" value="city" checked> City</label>
 <label><input type="checkbox" value="people" checked> People</label>
</div>

Ändern Sie dann die Filterlogik, um eine Reihe aktiver Kategorien zu erstellen:

function filterPhotosByCheckboxes() {
 const checked = document.querySelectorAll('#filter-checkboxes input:checked');
 const activeCategories = Array.from(checked).map(cb => cb.value);

 photos.forEach(photo => {
 const photoCategories = photo.dataset.category.split(' ');
 const shouldShow = activeCategories.length === 0 ||
 photoCategories.some(cat => activeCategories.includes(cat));
 photo.style.display = shouldShow ? '' : 'none';
 });
 sortPhotos(activeSort);
}

Wenn keine Checkboxen aktiviert sind, können Sie alle Bilder anzeigen (wie im Code oben) oder keine anzeigen - definieren Sie die gewünschte UX.

Text Search Input

Fügen Sie ein Eingabefeld hinzu, das Beschriftungen oder das Attribut durchsucht:

<input type="text" id="search" placeholder="Search photos...">
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', () => {
 const query = searchInput.value.toLowerCase();
 photos.forEach(photo => {
 const name = photo.dataset.name.toLowerCase();
 // Also search in caption if present
 const caption = photo.querySelector('.photo-caption')?.innerText.toLowerCase() || '';
 const matches = name.includes(query) || caption.includes(query);
 // If a filter is active, also check category
 const filter = activeFilter;
 const catMatch = filter === 'all' || photo.dataset.category.split(' ').includes(filter);
 photo.style.display = (matches && catMatch) ? '' : 'none';
 });
 sortPhotos(activeSort);
});

Kombinieren Sie die Suche mit Filtertasten, um die Ergebnisse weiter zu verengen. Beachten Sie, dass Sie den aktuellen Filterzustand speichern müssen, um ihn während der Suche zu respektieren.

Leistung und Zugänglichkeit

Eine dynamische Galerie sollte schnell und für jeden nutzbar sein, auch für Menschen, die assistierende Technologien verwenden.

Lazy Loading Bilder

Wir haben bereits verwendet, das das Laden aufschiebt, bis das Bild in der Nähe des Viewports ist. Für ältere Browser können Sie ein JavaScript-Lazy-Loading-Fallback mit der Intersection Observer API implementieren. Dies stellt sicher, dass auch wenn das native Lazy-Lady-Laden nicht unterstützt wird, Off-Screen-Bilder nicht geladen werden, wodurch die Bandbreite reduziert und die wahrgenommene Leistung verbessert wird.

Entlarven der Sucheingabe

Wenn Sie den Such-Listener an anhängen, feuert er bei jedem Tastendruck. Für große Galerien sollten Sie den Handler entprellen (z. B. 200ms Verzögerung), um übermäßige DOM-Manipulationen zu vermeiden.

function debounce(func, delay) {
 let timeoutId;
 return function (...args) {
 clearTimeout(timeoutId);
 timeoutId = setTimeout(() => func.apply(this, args), delay);
 };
}
searchInput.addEventListener('input', debounce(handleSearch, 200));

Keyboard Navigation

Filter and sort buttons should be focusable and operable via keyboard. Using native <button> elements already provides keyboard interaction (Enter/Space). Ensure that after filtering or sorting, focus is managed logically; for example, you could move focus to the first photo after a filter change via a focusable element. Also, consider adding aria-pressed attributes to filter buttons to indicate toggle state.

Announcing Changes to Screen Readers

Use an ARIA live region to announce filter and sort results:

<div id="gallery-announce" aria-live="polite" class="sr-only"></div>

Aktualisieren Sie nach jeder Filter-/Sortieraktion den Text dieses Elements, z. B. „8 nach Namen sortierte Naturfotos anzeigen. Dies hilft Benutzern, die sich auf Bildschirmleser verlassen, zu verstehen, was sich geändert hat.

CSS für Hidden Content

Anstatt allein zu verwenden, sollten Sie eine CSS-Klasse wie verwenden, die das Element verbirgt und es aus dem Accessibility-Baum entfernt:

.hidden {
 display: none !important;
 visibility: hidden;
}

Wenn Sie verwenden, entfernen Sie Elemente aus dem Accessibility-Baum, was angemessen ist.

Schlussfolgerung

Durch die Kombination von sauberem semantischem HTML, responsivem CSS und gut strukturiertem JavaScript können Sie eine dynamische Fotogalerie erstellen, die schnell, zugänglich und angenehm zu bedienen ist. Die abgedeckten Techniken - Filtern nach Kategorie (einschließlich mehrerer Kategorien), Sortieren nach verschiedenen Attributen, Hinzufügen von Textsuche und Optimierung der Leistung - bieten eine solide Grundlage, die mit Funktionen wie Paginierung, unendliches Bildrollen oder Integration mit einer Backend-API erweitert werden kann.

Für weitere Informationen erklärt die MDN-Dokumentation auf Array.prototype.sort() den Sortieralgorithmus und die web.dev responsive design guide bietet zusätzliche Layout-Tipps. Experimentieren Sie mit verschiedenen Datenattributen, Animationen und benutzerdefiniertem Styling, um die Galerie auf die Bedürfnisse Ihres Projekts zuzuschneiden. Das Ergebnis ist eine leistungsstarke, interaktive Komponente, die den Benutzern die Kontrolle über ihre Browsererfahrung gibt.