Spare 20 % mit WELCOMEAngebote ansehen
FiveM-Ladebildschirm

So erstellst du einen benutzerdefinierten FiveM-Ladebildschirm

Okay, lass uns überprüfen, wie man einen einzigartigen und fesselnden Einstiegspunkt für deine Spieler erstellt.

Wir bauen ein Benutzerdefinierter FiveM-Ladebildschirm von Grund auf.

Was ist eine Ladebildschirmressource?

Ein benutzerdefinierter Ladebildschirm ist oft die allererste Interaktion, die ein Spieler mit deinem spezifischen FiveM-Server hat.

Es ist eine fantastische Gelegenheit, die Marke deines Servers zu etablieren, wichtige Informationen zu vermitteln und eine detaillierte Atmosphäre von Anfang an zu schaffen.

Vergesst die generischen FiveM-Grafiken; wir wollen, dass die Spieler sich fühlen dein Die Identität des Servers wird in dem Moment erkannt, in dem die Verbindung hergestellt wird.

Hier bei FiveMX glauben wir daran, Server-Besitzer mit den Werkzeugen und dem Wissen auszustatten, um wirklich spezifische Rollenspiel-Setups zu erstellen.

Dieser umfassende Leitfaden führt dich durch jeden Schritt, von der grundlegenden HTML-Struktur über das Styling mit CSS, das Hinzufügen von Interaktivität mit JavaScript und schließlich die Integration in deinen FiveM-Server unter Verwendung von Lua.

Wir decken sogar, wie du die Standard-FiveM-Brückenanimation ausblendest, für einen sauberen Übergang.

Lass uns mit der Gestaltung deines Servers beginnen, um ihn von anderen abzuheben.

Warum sich mit einem benutzerdefinierten FiveM-Ladebildschirm herumschlagen?

Du fragst dich vielleicht, ob es sich lohnt.

Absolut!

Stell dir das als den Eingangsbereich oder die Lobby deiner virtuellen Welt vor.

Erste Eindrücke: Es setzt den Ton und die Professionalität deines Servers sofort.

Markenbildung: Stärke den Namen, das Logo und das Gesamtbild deines Servers.

Informationsanzeige: Teile wichtige Informationen wie Regeln, Discord-Links, Website-URLs oder Serverstatus-Updates vor Es spawnen sogar Spieler darin.

Engagement: Nutze Musik, dynamische Nachrichten oder sogar Videos, um die Spieler während des Ladevorgangs bei Laune zu halten und die Wartezeit zu verkürzen.

Einzigartigkeit: Hebe deinen Server von den unzähligen anderen ab, die Standard- oder generische Bildschirme verwenden.

Ein gut gestalteter Ladescreen zeigt, dass du auf Details und das Spielerlebnis achtest.

Voraussetzungen

Bevor wir mit dem Codieren beginnen, lass uns sicherstellen, dass du die notwendigen Tools und Grundkenntnisse hast:

  1. Texteditor: Du brauchst ein Programm, um deinen Code zu schreiben.
    • Visual Studio Code (VS Code): Kostenlos, leistungsstark und sehr empfehlenswert, mit vielen hilfreichen Erweiterungen.
    • Sublime Text: Eine weitere beliebte, leichte Option.
    • Notepad++: Eine solide kostenlose Wahl für Windows-Benutzer.
    • Vermeiden mit grundlegendem Notepad oder TextEdit, da ihnen Funktionen fehlen, die beim Codieren hilfreich sind (wie Syntax-Hervorhebung).
  2. Grundlegende Kenntnisse in der Webentwicklung (hilfreich, nicht unbedingt erforderlich):
    • HTML (HyperText Markup Language): Versteht die grundlegende Struktur einer Webseite (Tags wie <div>, <img>, <p>). Wir stellen den Code zur Verfügung, aber es ist hilfreich, die Grundlagen zu kennen.
    • CSS (Cascading Style Sheets): Kennt sich mit dem Styling von HTML-Elementen aus (Farben, Größen, Positionen). Wir werden dich führen, aber Vertrautheit ist ein Plus.
    • JavaScript (JS): Versteht grundlegende Programmierkonzepte zum Hinzufügen von Interaktivität. Wir halten das JS zunächst relativ einfach.
  3. Zugriff auf den FiveM-Server: Du benötigst Zugriff auf die Dateien deines Servers, speziell die Ressourcen Ordner, um den Ladebildschirm zu installieren.
  4. Bildbearbeitungssoftware (optional): Tools wie Photoshop, GIMP (kostenlos) oder sogar Canva können zum Erstellen oder Bearbeiten von Logos und Hintergrundbildern nützlich sein.
  5. Geduld und Lernbereitschaft: Debuggen und Optimieren sind Teil des Prozesses!

Mach dir keine Sorgen, wenn du kein Experte in Webentwicklung bist.

Wir erklären jeden Schritt klar und deutlich und stellen kopier- und einfügbare Codeausschnitte bereit.

Verstehen, wie FiveM-Ladebildschirme funktionieren (NUI)

FiveM nutzt ein System namens NUI (Native UI) zur Anzeige von Webseiten innen das Spiel.

Im Wesentlichen ist Ihr benutzerdefinierter Ladebildschirm nur eine Standardwebseite (erstellt mit HTML, CSS und JavaScript), die das NUI-System von FiveM rendert, während die Spielressourcen im Hintergrund geladen werden.

Das bedeutet, dass wir Standard-Webtechnologien nutzen können, um visuell ansprechende und interaktive Erlebnisse zu schaffen.

Der Kern Komponenten sind:

  • Hauptseite: Die Hauptdatei, die die Struktur und den Inhalt deines Ladescreens definiert.
  • Stil.css: Die Datei, die das visuelle Erscheinungsbild (Layout, Farben, Schriftarten usw.) definiert.
  • script.js: Die Datei, die dynamisches Verhalten hinzufügt (wie Textänderungen, Animationen, Musikwiedergabe).
  • fxmanifest.lua (oder __resource.lua): Eine spezielle FiveM-Datei, die dem Server mitteilt, dass es sich um eine Ressource handelt, angibt, dass es sich um einen Ladebildschirm handelt, und alle erforderlichen Dateien auflistet.

Beginnen wir nun mit dem Bauen.

Schritt 1: Erstellen der grundlegenden HTML-Struktur (Hauptseite)

Erstelle zuerst einen neuen Ordner für deine Ladebildschirm-Ressource. Nennen wir ihn mein-Ladebildschirm.

In diesem Ordner erstellst du eine Datei mit dem Namen Hauptseite.

Diese Datei enthält das Grundgerüst unseres Ladebildschirms.

Wir benötigen Container für verschiedene Elemente: den Hintergrund, ein Logo, eine Ladefortschrittsanzeige und Bereiche für Textnachrichten.

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Servername – Wird geladen …</title>
 <!-- Link to your CSS file -->
 <link rel="stylesheet" href="style.css">
</head>
<body>

 <!-- Main container for the entire screen -->
 <div class="loading-container">

 <!-- Background Element (handled by CSS) -->
 <div class="background"></div>

 <!-- Content Wrapper -->
 <div class="content">

 <!-- Logo Area -->
 <div class="logo-area">
 <img src="Bilder/Logo.png" alt="Server-Logo" id="server-logo">
 <!-- You can replace img with text if you prefer -->
 <!-- <h1>My Awesome Server</h1> -->
 </div>

 <!-- Message Area -->
 <div class="message-area">
 <p id="loading-message">Verbindung wird initialisiert...</p>
 <p id="dynamic-message">Willkommen! Serverressourcen werden geladen …</p>
 </div>

 <!-- Progress Bar Area -->
 <div class="progress-bar-container">
 <div class="progress-bar">
 <div class="progress-bar-inner" id="progress-bar-inner"></div>
 </div>
 <p id="progress-text">0%</p>
 </div>

 <!-- Music Control (Optional) -->
 <div class="music-control">
 <button id="play-pause-button">Musik pausieren</button>
 <input type="range" id="volume-slider" min="0" max="1" step="0.01" value="0.5">
 </div>

 </div> <!-- End Content Wrapper -->

 </div> <!-- End Loading Container -->

 <!-- Link to your JavaScript file (place at the end of body) -->
 <script src="script.js"></script>
</body>
</html>

Erläuterung:

  • und <html>: Standard-HTML5-Boilerplate.
  • : Enthält Metainformationen und Links zu externen Ressourcen.
    • Zeichensatz="UTF-8": Sorgt für die korrekte Zeichenanzeige.
    • Ansichtsfenster: Wichtig für responsives Design (Anpassung an unterschiedliche Bildschirmgrößen), jedoch weniger kritisch für Ladebildschirme von Spielen mit fester Auflösung.
    • </code>: Legt den Text fest, der in einem Browser-Tab angezeigt werden kann (weniger relevant in FiveM NUI, aber bewährte Methode).</li> <li><code></code>: Verbindet unser HTML mit unserer CSS-Datei zur Formatierung.</li> </ul> </li> <li><strong><code><body></code>:</strong> Enthält den sichtbaren Inhalt der Seite.</li> <li><strong><code><div class="loading-container"></code>:</strong> Der Haupt-Wrapper für alles. Wir verwenden ihn für das Gesamtlayout.</li> <li><strong><code><div class="background"></code>:</strong> Ein leeres Div, das wir mit CSS formatieren, um unser Hintergrundbild oder -video aufzunehmen.</li> <li><strong><code><div class="content"></code>:</strong> Umschließt den eigentlichen Inhalt (Logo, Text, Fortschrittsbalken), um die Zentrierung und Positionierung zu erleichtern.</li> <li><strong><code><div class="logo-area"></code>:</strong> Ein Behälter für das Logo deines Servers. <ul class="wp-block-list"> <li><code><img src="Bilder/Logo.png" ...></code>: Ein Bild-Tag. <strong>Wichtig:</strong> Du musst ein <code>Bilder</code> Ordner im Inneren <code>mein-Ladebildschirm</code> und lege deine <code>logo.png</code> Datei dort. Stelle sicher, dass der Dateiname übereinstimmt!</li> </ul> </li> <li><strong><code><div class="message-area"></code>:</strong> Enthält Textnachrichten. <ul class="wp-block-list"> <li>Wir geben Absätzen IDs (<code>Ladenachricht</code>, <code>dynamische Nachricht</code>), damit wir sie später problemlos mit JavaScript ansprechen können.</li> </ul> </li> <li><strong><code><div class="progress-bar-container"></code>:</strong> Enthält die Elemente des Fortschrittsbalkens. <ul class="wp-block-list"> <li><code>.Fortschrittsbalken</code>: Der äußere Behälter des Riegels.</li> <li><code>.Fortschrittsbalken-inner</code>: Der innere Teil, der gefüllt wird. Wir geben ihm eine ID (<code>Fortschrittsbalken-innen</code>) zur JS-Steuerung.</li> <li><code><p id="progress-text"></code>: Zeigt den Prozenttext an, auch mit einer ID.</li> </ul> </li> <li><strong><code><div class="music-control"></code>:</strong> (Optional) Grundlegende Steuerelemente für Hintergrundmusik. IDs ermöglichen JS-Interaktion.</li> <li><strong><code></code>:</strong> Verknüpft unser HTML mit unserer JavaScript-Datei. Platziere es am Ende des <code><body></code> stellt sicher, dass die HTML-Elemente vorhanden sind, bevor das Skript versucht, mit ihnen zu interagieren.</li> </ul> <p class="wp-block-paragraph">Speichere diese Datei als <code>Hauptseite</code> in deinem <code>mein-Ladebildschirm</code> Ordner. Erstelle ein <code>Bilder</code> Unterordner und füge einen Platzhalter hinzu <code>logo.png</code> zur Zeit.</p> <h2 class="wp-block-heading" id="step-2-styling-the-loading-screen-css-style-css">Schritt 2: Styling des Ladebildschirms (CSS – <code>Stil.css</code>)</h2> <p class="wp-block-paragraph">Und jetzt lasst es uns gut aussehen!</p> <p class="wp-block-paragraph">Erstelle eine Datei mit dem Namen <code>Stil.css</code> im gleichen <code>mein-Ladebildschirm</code> Ordner.</p> <p class="wp-block-paragraph">Diese Datei steuert die visuelle Darstellung.</p> <pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">/* Grundlegendes Zurücksetzen & Body-Styling */ * { margin: 0; padding: 0; box-sizing: border-box; /* Macht Breite/Höhe inklusive Padding und Rand */ } body, html { height: 100%; width: 100%; overflow: hidden; /* Scrollbalken ausblenden */ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* Beispielschriftart */ color: #ffffff; /* Standardtextfarbe (weiß) */ } /* Hauptcontainer */ .loading-container { position: relative; /* Benötigt für absolute Positionierung der Kinder */ width: 100%; height: 100%; display: flex; /* Verwende Flexbox zum Zentrieren des Inhalts */ justify-content: center; align-items: center; text-align: center; } /* Hintergrund-Styling */ .background { position: absolute; /* Nimmt den gesamten Bildschirm hinter dem Inhalt ein */ top: 0; left: 0; width: 100%; height: 100%; background-image: url('images/background.jpg'); /* ÄNDERE DAS zu deinem Bild */ background-size: cover; /* Skaliere das Bild, um den Container zu bedecken */ background-position: center center; /* Zentriere das Bild */ background-repeat: no-repeat; z-index: -1; /* Platziere es hinter anderem Inhalt */ filter: brightness(0.6); /* Optional: Verdunkle den Hintergrund leicht */ } /* --- ODER Verwende einen Einfarbigen Hintergrund --- */ /* .background { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: #1a1a1a; z-index: -1; } */ /* Inhaltswrapper */ .content { z-index: 1; /* Stelle sicher, dass der Inhalt über dem Hintergrund liegt */ padding: 20px; background-color: rgba(0, 0, 0, 0.5); /* Halbtransparenter schwarzer Hintergrund */ border-radius: 10px; max-width: 600px; /* Begrenzte Inhaltsbreite */ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.4); } /* Logo-Bereich */ .logo-area { margin-bottom: 30px; } #server-logo { max-width: 200px; /* Passe die maximale Logo-Breite an */ height: auto; /* Behalte das Seitenverhältnis bei */ display: block; /* Ermöglicht margin auto zum Zentrieren */ margin-left: auto; margin-right: auto; } /* Nachrichtenbereich */ .message-area { margin-bottom: 30px; } #loading-message { font-size: 1.2em; font-weight: bold; margin-bottom: 10px; color: #cccccc; } #dynamic-message { font-size: 1em; min-height: 40px; /* Verhindere Layout-Verschiebungen, wenn sich die Nachricht ändert */ } /* Fortschrittsbalken-Bereich */ .progress-bar-container { width: 80%; /* Breite relativ zum Inhaltscontainer */ margin: 0 auto; /* Zentriere den Container */ margin-bottom: 20px; } .progress-bar { width: 100%; background-color: #555555; /* Dunkler grauer Hintergrund */ border-radius: 5px; overflow: hidden; /* Verstecke den überlaufenden inneren Balken */ height: 25px; /* Balkenhöhe */ border: 1px solid #333; } .progress-bar-inner { height: 100%; width: 0%; /* Starte mit 0% Breite */ background-color: #4CAF50; /* Grüne Fortschrittsfarbe */ border-radius: 5px 0 0 5px; /* Behalte den linken Radius */ transition: width 0.5s ease-in-out; /* Sanfter Übergang für Breitenänderungen */ text-align: center; line-height: 25px; /* Vertikales Zentrieren von Text, falls nötig, im Inneren */ color: white; } #progress-text { margin-top: 5px; font-size: 0.9em; } /* Musiksteuerung (Optional) */ .music-control { margin-top: 25px; display: flex; /* Anordnung der Schaltfläche und des Reglers nebeneinander */ justify-content: center; align-items: center; gap: 15px; /* Abstand zwischen den Elementen */ } #play-pause-button { padding: 8px 15px; background-color: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer; font-size: 0.9em; transition: background-color 0.3s ease; } #play-pause-button:hover { background-color: #45a049; } #volume-slider { cursor: pointer; width: 150px; /* Passe die Reglerbreite an */ } /* Füge etwas grundlegende Reaktionsfähigkeit hinzu, falls nötig, obwohl dies in NUI weniger kritisch ist */ @media (max-width: 600px) { .content { max-width: 90%; } .progress-bar-container { width: 90%; } }</pre> <p class="wp-block-paragraph"><strong>Erläuterung:</strong></p> <ul class="wp-block-list"> <li><strong><code>* { Box-Größe: Rahmenbox; }</code></strong>: Ein allgemeiner Reset, um die Größenelemente vorhersehbarer zu machen.</li> <li><strong><code>Textkörper, HTML</code></strong>: Legt die Basishöhe/-breite fest und blendet mögliche Bildlaufleisten aus. Legt eine Standardschriftart und -textfarbe fest.</li> <li><strong><code>.Ladecontainer</code></strong>: Verwendet <code>Anzeige: Flex</code> zum einfachen Zentrieren des <code>.Inhalt</code> div sowohl horizontal (<code>Inhalt ausrichten</code>) und vertikal (<code>Elemente ausrichten</code>). <code>Position: relativ</code> ist entscheidend für die Positionierung des absoluten Hintergrunds.</li> <li><strong><code>.Hintergrund</code></strong>: <ul class="wp-block-list"> <li><code>Position: absolut</code>: Nimmt das Element aus dem normalen Fluss und positioniert es relativ zum nächstgelegenen positionierten Vorgänger (<code>.Ladecontainer</code>).</li> <li><code>oben: 0; links: 0; Breite: 100%; Höhe: 100%;</code>: Deckt den gesamten Container ab.</li> <li><code>Hintergrundbild: URL(...)</code>: <strong>Entscheidend ist, ändern <code>'Bilder/Hintergrund.jpg'</code> zum tatsächlichen Pfad deines Hintergrundbildes.</strong> Stelle sicher, dass das Bild im <code>Bilder</code> Ordner.</li> <li><code>Hintergrundgröße: Cover</code>: Skaliert das Bild gut.</li> <li><code>z-Index: -1</code>: Schiebt es hinter andere Elemente.</li> <li><code>Filter: Helligkeit (0,6)</code>: Ein optionaler Effekt, um den Hintergrund abzudunkeln, wodurch der Text besser lesbar wird. Passe ihn an oder entferne ihn nach Bedarf.</li> <li><em>Alternative:</em> Ein auskommentierter Abschnitt zeigt, wie man stattdessen eine einfache feste Hintergrundfarbe verwendet.</li> </ul> </li> <li><strong><code>.Inhalt</code></strong>: <ul class="wp-block-list"> <li><code>Z-Index: 1</code>: Stellt sicher, dass es über dem Hintergrund sitzt.</li> <li><code>Hintergrundfarbe: rgba(0, 0, 0, 0,5)</code>: Ein halbtransparenter schwarzer Hintergrund für den Inhaltsbereich selbst, der hilft, den Text gegen komplexe Hintergründe abzuheben. Passe den letzten Wert (Alpha) von 0 (vollständig transparent) bis 1 (vollständig undurchsichtig) an.</li> <li><code>Randradius</code>, <code>maximale Breite</code>, <code>Kastenschatten</code>: Füge etwas visuelles Finish hinzu.</li> </ul> </li> <li><strong><code>.Logo-Bereich</code>, <code>#server-Logo</code></strong>: Formatiert den Logo-Container und das Logo-Bild selbst (Einstellen der maximalen Breite, Zentrierung).</li> <li><strong><code>.Nachrichtenbereich</code>, <code>#Lademeldung</code>, <code>#dynamische Nachricht</code></strong>: Stilisiert die Textelemente (Schriftgröße, Farbe, Ränder). <code>Mindesthöhe</code> verhindert, dass das Layout springt, wenn sich die Länge des dynamischen Nachrichteninhalts ändert.</li> <li><strong><code>.Fortschrittsbalken-Container</code>, <code>.Fortschrittsbalken</code>, <code>.Fortschrittsbalken-inner</code></strong>: Gestaltet den Fortschrittsbalken. <ul class="wp-block-list"> <li>Der äußere Behälter (<code>.Fortschrittsbalken</code>) legt die Hintergrundfarbe und -form fest.</li> <li>Der innere Balken (<code>.Fortschrittsbalken-inner</code>) ist das, was wächst. Es beginnt bei <code>Breite: 0%</code>. Wir werden diese Breite mit JavaScript ändern. <code>Übergang: Breite 0,5 s, Ein- und Ausstieg;</code> macht die Breitenänderung reibungslos.</li> </ul> </li> <li><strong><code>.Musiksteuerung</code>, <code>#Play-Pause-Taste</code>, <code># Lautstärkeregler</code></strong>: Gestaltet die optionalen Musiksteuerungen mithilfe von Flexbox für das Layout und fügt grundlegende Schaltflächengestaltung hinzu.</li> <li><strong><code>@media (maximale Breite: 600px)</code></strong>: Ein einfaches Beispiel für eine Media-Abfrage zur Reaktionsfähigkeit. Es passt die Inhaltbreite auf kleineren Bildschirmen an (weniger kritisch für FiveM, aber gute Praxis).</li> </ul> <p class="wp-block-paragraph">Speichern unter <code>Stil.css</code>. Vergiss nicht, die <code>Bilder</code> Ordner und füge deine <code>Hintergrund.jpg</code> (oder wie du sie genannt hast) und <code>logo.png</code>.</p> <p class="wp-block-paragraph">An diesem Punkt könntest du technisch gesehen die <code>Hauptseite</code> Datei direkt in deinem Webbrowser (wie Chrome oder Firefox) anzeigen, um ihr statisches Aussehen vorab zu betrachten!</p> <h2 class="wp-block-heading" id="step-3-adding-interactivity-dynamic-content-java-script-script-js">Schritt 3: Interaktivität und dynamische Inhalte hinzufügen (JavaScript – <code>script.js</code>)</h2> <p class="wp-block-paragraph">Jetzt lass uns unserem statischen Bildschirm mit JavaScript etwas Leben einhauchen.</p> <p class="wp-block-paragraph">Erstelle eine Datei mit dem Namen <code>script.js</code> in deinem <code>mein-Ladebildschirm</code> Ordner.</p> <p class="wp-block-paragraph">Wir fügen Funktionen für Folgendes hinzu:</p> <ol class="wp-block-list"> <li>Simulation des Ladevorgangs.</li> <li>Anzeige dynamischer/veränderlicher Nachrichten.</li> <li>Hinzufügen von Hintergrundmusik mit Steuerelementen.</li> <li>Handhabung von FiveM NUI-Ereignissen (die richtige Methode, um den Ladefortschritt zu ermitteln).</li> </ol> <pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// Wait for the DOM (Document Object Model - the HTML structure) to be fully loaded document.addEventListener('DOMContentLoaded', () => { // --- Get References to HTML Elements --- const progressBarInner = document.getElementById('progress-bar-inner'); const progressText = document.getElementById('progress-text'); const dynamicMessage = document.getElementById('dynamic-message'); const loadingMessage = document.getElementById('loading-message'); // To update stages // --- Configuration --- const messages = [ "Loading core systems...", "Establishing network connection...", "Downloading latest server assets...", "Syncing player data...", "Parsing map details...", "Almost there, preparing the world...", "Tip: Visit our Discord at discord.gg/yourinvite", "Tip: Check the rules on our website yourwebsite.com", "Welcome to Our Awesome Server!" ]; let currentMessageIndex = 0; const messageChangeInterval = 5000; // Change message every 5 seconds (5000ms) // Background Music (Optional) const backgroundMusic = new Audio('audio/background_music.ogg'); // IMPORTANT: Use .ogg for FiveM compatibility backgroundMusic.volume = 0.5; // Set initial volume (0.0 to 1.0) backgroundMusic.loop = true; // Loop the music const playPauseButton = document.getElementById('play-pause-button'); const volumeSlider = document.getElementById('volume-slider'); let isPlaying = false; // Track music state // --- Functions --- // Function to update the progress bar and text function updateProgress(percentage) { percentage = Math.min(100, Math.max(0, percentage)); // Clamp between 0 and 100 progressBarInner.style.width = `${percentage}%`; progressText.textContent = `${Math.round(percentage)}%`; } // Function to change the dynamic message function changeDynamicMessage() { dynamicMessage.style.opacity = 0; // Fade out setTimeout(() => { currentMessageIndex = (currentMessageIndex + 1) % messages.length; dynamicMessage.textContent = messages[currentMessageIndex]; dynamicMessage.style.opacity = 1; // Fade in }, 500); // Wait for fade out transition (0.5s) } // Function to attempt playing music (handles browser autoplay restrictions) function playMusic() { backgroundMusic.play().then(() => { isPlaying = true; playPauseButton.textContent = 'Pause Music'; console.log("Music started playing."); }).catch(error => { // Autoplay was prevented, common in browsers until user interaction console.log("Music autoplay failed. Waiting for user interaction.", error); isPlaying = false; playPauseButton.textContent = 'Play Music'; // We might need a click listener on the body or button to initiate playback }); } // --- Initial Setup --- // Set initial loading message loadingMessage.textContent = "Initializing..."; updateProgress(0); // Start progress at 0% // Start changing dynamic messages dynamicMessage.textContent = messages[0]; // Show the first message immediately setInterval(changeDynamicMessage, messageChangeInterval); // Try to play music automatically playMusic(); // Attempt background music playback // --- Event Listeners --- // Music Controls Event Listeners playPauseButton.addEventListener('click', () => { if (isPlaying) { backgroundMusic.pause(); isPlaying = false; playPauseButton.textContent = 'Play Music'; } else { // Important: Re-trigger play function which handles potential initial failures playMusic(); } }); volumeSlider.addEventListener('input', (event) => { backgroundMusic.volume = event.target.value; }); // --- FiveM NUI Event Handling --- // This is the CORE of interacting with the FiveM loading process /* FiveM NUI messages are sent via JavaScript events. We listen for 'message' events on the window object. The event 'data' property contains the information sent from Lua. */ window.addEventListener('message', function(event) { const data = event.data; // Check for the specific NUI message type used by FiveM for loading progress // The 'loadstatus' event provides overall progress text. if (data.type === 'loadstatus') { if(data.status) { loadingMessage.textContent = data.status; } } // The 'progress' event provides detailed component progress (use this for the bar) else if (data.eventName === 'progress') { // data.loadFraction gives a value between 0.0 and 1.0 const progressPercentage = data.loadFraction * 100; updateProgress(progressPercentage); } // A custom event we might send from Lua when loading is almost done else if (data.type === 'loadingComplete') { updateProgress(100); loadingMessage.textContent = "Loading Complete! Joining server..."; // You could add fade-out effects here before the screen disappears } }); // --- Fallback/Simulated Progress (If NUI events aren't received or for testing) --- // Comment this out or remove it if you rely solely on FiveM NUI events /* let simulatedProgress = 0; const interval = setInterval(() => { simulatedProgress += Math.random() * 5; // Increment by a random small amount if (simulatedProgress >= 100) { simulatedProgress = 100; clearInterval(interval); // Stop the simulation when 100% is reached loadingMessage.textContent = "Loading Complete! Joining server..."; // Update final message } updateProgress(simulatedProgress); }, 300); // Update every 300ms */ // Add a small fade-in effect for the whole screen on load document.body.style.opacity = 0; setTimeout(() => { document.body.style.transition = 'opacity 1s ease-in-out'; document.body.style.opacity = 1; }, 100); // Start fade-in slightly after load }); // End DOMContentLoaded</pre> <p class="wp-block-paragraph"><strong>Erläuterung:</strong></p> <ol class="wp-block-list"> <li><strong><code>document.addEventListener('DOMContentLoaded', () => { ... });</code></strong>: Dadurch wird sichergestellt, dass der JavaScript-Code nur ausgeführt wird <em>nach</em> Die gesamte HTML-Seitenstruktur wurde geladen und kann bearbeitet werden.</li> <li><strong>Elementreferenzen:</strong> Wir erhalten Verweise auf die HTML-Elemente, mit denen wir interagieren müssen, indem wir <code>document.getElementById()</code>Aus diesem Grund ist es wichtig, im HTML eindeutige IDs zu haben.</li> <li><strong>Konfiguration:</strong> <ul class="wp-block-list"> <li><code>Nachrichten</code>: Ein Array, das die verschiedenen Textzeilen enthält, die du im dynamischen Nachrichtenbereich durchlaufen lassen möchtest. Passe diese an!</li> <li><code>aktuellerNachrichtenindex</code>: Behält den Überblick darüber, welche Nachricht aktuell angezeigt wird.</li> <li><code>Nachrichtenänderungsintervall</code>: Legt fest, wie oft (in Millisekunden) sich die Nachricht ändert.</li> </ul> </li> <li><strong>Hintergrundmusik-Setup:</strong> <ul class="wp-block-list"> <li><code>neues Audio('audio/hintergrundmusik.ogg')</code>: Erstellt ein HTML-Audioobjekt. <strong>Entscheidend:</strong> <ul class="wp-block-list"> <li>Erstelle ein <code>Audio-</code> Ordner im Inneren <code>mein-Ladebildschirm</code>.</li> <li>Lege deine Hintergrundmusikdatei dort hin.</li> <li><strong>Verwende den <code>.ogg</code> Format!</strong> MP3 und andere Formate können in FiveM NUI unzuverlässig sein oder überhaupt nicht funktionieren. Online-Konverter zum Konvertieren von MP3 in OGG sind problemlos verfügbar.</li> </ul> </li> <li><code>Hintergrundmusik.Lautstärke</code>: Legt die Anfangslautstärke fest (0,0 = leise, 1,0 = voll).</li> <li><code>Hintergrundmusik.Schleife = true;</code>: Lässt die Musik wiederholen.</li> <li>Wir erhalten auch Hinweise auf die Wiedergabe-/Pause-Taste und den Lautstärkeregler.</li> </ul> </li> <li><strong><code>Update-Fortschritt (Prozentsatz)</code> Funktion:</strong> Nimmt eine Zahl (0-100), klemmt sie, um sicherzustellen, dass sie innerhalb der Grenzen liegt, aktualisiert die <code>Breite</code> Stil des inneren Fortschrittsbalkenelements und ändert den Textinhalt der Prozentanzeige.</li> <li><strong><code>changeDynamicMessage()</code> Funktion:</strong> <ul class="wp-block-list"> <li>Anwendung <code>Intervall festlegen</code> in der Setup-Phase, um diese Funktion wiederholt aufzurufen.</li> <li>Es berechnet den Index der nächsten Nachricht und verwendet dabei den Modulo-Operator (<code>%</code>).</li> <li>Aktualisiert die <code>textContent</code> der <code>dynamischeNachricht</code> Element.</li> <li><em>Bonus:</em> Enthält einen einfachen Aus-/Einblendeffekt mit CSS-Opazität und <code>setTimeout</code> für einen sanfteren Übergang. Hinzufügen <code>Übergang: Deckkraft 0,5 s, Ein-Aus;</code> zur <code>.Nachrichtenbereich p</code> Auswahlliste in deinem CSS verwenden, damit dies visuell funktioniert.</li> </ul> </li> <li><strong><code>Musik abspielen()</code> Funktion:</strong> Versuche, die Musik abzuspielen mit <code>backgroundMusic.play()</code>. Der <code>.Dann()</code> kümmert sich um die erfolgreiche Wiedergabe, während <code>.fangen()</code> Behandelt Fehler, die häufig aufgrund von Browser-Autoplay-Einschränkungen auftreten (da hierfür zunächst eine Benutzerinteraktion erforderlich ist). Der Schaltflächentext wird entsprechend aktualisiert.</li> <li><strong>Ersteinrichtung:</strong> Legt den Anfangstext fest, setzt den Fortschritt auf 0 zurück, zeigt die erste dynamische Nachricht an und startet den Intervalltimer für Nachrichtenänderungen. Außerdem ruft es <code>Musik abspielen()</code> um zu versuchen, die Audiowiedergabe zu starten.</li> <li><strong>Ereignis-Listener (Musiksteuerung):</strong> <ul class="wp-block-list"> <li>Hört auf Klicks auf dem <code>PlayPauseButton</code>. Wenn Musik läuft, pausiert es diese, andernfalls ruft es <code>Musik abspielen()</code> erneut (wichtig zur Behandlung von Fällen, in denen die anfängliche automatische Wiedergabe fehlgeschlagen ist).</li> <li>Hört auf <code>Eingang</code> Ereignisse auf der <code>Lautstärkeregler</code> (wird kontinuierlich ausgelöst, wenn sich der Schieberegler bewegt) und aktualisiert die <code>Hintergrundmusik.Lautstärke</code>.</li> </ul> </li> <li><strong>FiveM NUI-Ereignisbehandlung (<code>window.addEventListener('Nachricht', ...)</code>):</strong> <ul class="wp-block-list"> <li><strong>Dies ist der wichtigste Teil für <em>real</em> Integration.</strong> FiveM sendet Nachrichten an das NUI-Fenster (deine HTML-Seite) unter Verwendung des <code>PostMessage</code> API.</li> <li>Wir hören diese Nachrichten auf dem <code>Fenster</code> Objekt.</li> <li><code>Ereignisdaten</code> enthält die Nutzlast, die gesendet wird von <a href="https://fivemx.com/de/konvertieren-von-fivem-skripten/" title="Konvertieren von FiveM-Skripten – ESX, QBCore, QBOX (Framework-Handbuch)" data-wpil-monitor-id="1644">Lua-Skripte von FiveM</a>.</li> <li>Wir prüfen <code>Ereignisdatentyp</code> oder <code>Ereignis.Daten.Ereignisname</code> (verschiedene FiveM-Versionen/Kontexte verwenden möglicherweise leicht unterschiedliche Strukturen), um zu sehen, um welche Art von Nachricht es sich handelt.</li> <li><code>'Ladestatus'</code>: Enthält oft allgemeinen Statustext (z. B. „Karte wird geladen“, „Skripte werden initialisiert“). Wir aktualisieren die <code>Nachricht wird geladen</code> Absatz.</li> <li><code>'Fortschritt'</code>: Dies wird normalerweise für den tatsächlichen Ladebalkenfortschritt verwendet. <code>data.loadFraction</code> liefert in der Regel einen Wert von 0,0 bis 1,0, den wir in einen Prozentsatz umwandeln und in unsere <code>Aktualisierungsfortschritt</code> Funktion.</li> <li><code>„Laden abgeschlossen“</code>: Dies ist kein Standard-FiveM-Event, sondern ein Beispiel für ein <em>Brauch</em> Nachricht an dich <em>könnte</em> Sende von einem Lua-Skript (das wir später besprechen) ein Signal zum Ende des Ladens, damit du den Fortschritt auf 100% setzen und eine abschließende Nachricht anzeigen kannst.</li> </ul> </li> <li><strong>Fallback/Simulierter Fortschritt:</strong> <ul class="wp-block-list"> <li>Der auskommentierte Abschnitt bietet eine <em>Basissimulation</em> des Fortschritts. Es nutzt <code>Intervall festlegen</code> um den Fortschrittsbalken regelmäßig um einen kleinen zufälligen Betrag zu erhöhen.</li> <li><strong>Das ist nützlich, um deinen Ladebildschirm visuell in einem Browser zu testen <em>ohne</em> FiveM ausführen.</strong></li> <li><strong>Du solltest diesen Simulationscode entfernen oder AUSKOMMENTIEREN, wenn du die tatsächlichen FiveM NUI-Ereignisse verwendest</strong>, andernfalls könntest du sich widersprechende Fortschrittsaktualisierungen sehen.</li> </ul> </li> <li><strong>Einblendeffekt:</strong> Fügt beim Laden der Seite eine subtile Einblendung für den gesamten Text hinzu, um ein flüssigeres Erscheinungsbild zu erzielen.</li> </ol> <p class="wp-block-paragraph">Speichere diese Datei als <code>script.js</code>. Vergiss nicht, die <code>Audio-</code> Ordner und füge deine <code>.ogg</code> Musikdatei.</p> <h2 class="wp-block-heading" id="step-4-integrating-with-five-m-lua-fxmanifest-lua">Schritt 4: Integration mit FiveM (Lua – <code>fxmanifest.lua</code>)</h2> <p class="wp-block-paragraph">Jetzt müssen wir dem FiveM-Server von unserer neuen Ressource erzählen und sie als Ladebildschirm identifizieren.</p> <p class="wp-block-paragraph">Erstelle eine Datei mit dem Namen <code>fxmanifest.lua</code> im Stammverzeichnis deines <code>mein-Ladebildschirm</code> Ordner.</p> <pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">-- Ressourcenmanifest fx_version 'cerulean' -- Verwende 'cerulean' oder eine neuere Version wie 'adamant' oder 'bodacious' game 'gta5' author 'Dein Name oder Servername' description 'Benutzerdefinierter Ladescreen für meinen tollen Server' version '1.0.0' -- Definiere diese Ressource als Ladescreen loadscreen 'index.html' -- Liste alle Dateien, die von der UI benötigt werden (HTML, CSS, JS, Bilder, Audio, Schriftarten usw.) files { 'index.html', 'style.css', 'script.js', 'images/logo.png', 'images/background.jpg', -- Füge hier alle deine Bilder hinzu 'audio/background_music.ogg' -- Füge hier alle deine Audiodateien hinzu -- 'fonts/mycustomfont.woff2' -- Füge benutzerdefinierte Schriftarten hinzu, falls du welche verwendest } -- Optional: Client-Skript für erweiterte Steuerung (z. B. Ausblenden von Standardelementen) client_script 'client.lua' -- Optional: Falls dein Ladescreen Daten vom Server abrufen muss (fortgeschrittener) -- server_script 'server.lua' -- Optional: Definiere NUI-Einstellungen, falls erforderlich (selten für einfache Ladescreens benötigt) -- nui_settings { -- ['scriptFramePolicy'] = "frame-ancestors 'self' https://cfx.re" -- Beispiel-Sicherheitspolitik -- }</pre> <p class="wp-block-paragraph"><strong>Erläuterung:</strong></p> <ul class="wp-block-list"> <li><strong><code>fx_version 'himmelblau'</code></strong>: Definiert die Manifestversion. ‘cerulean’ ist eine häufige Basislinie, aber neuere Versionen wie ‘adamant’ oder ‘bodacious’ existieren. Bleibe bei ‘cerulean’, es sei denn, du benötigst Funktionen aus neueren Versionen.</li> <li><strong><code>Spiel 'gta5'</code></strong>: Gibt das Spiel an, für das diese Ressource bestimmt ist.</li> <li><strong><code>Autor</code>, <code>Beschreibung</code>, <code>Version</code></strong>: Metadaten über deine Ressource. Fülle diese entsprechend aus.</li> <li><strong><code>Ladebildschirm „index.html“</code></strong>: <strong>Dies ist die entscheidende Zeile.</strong> Es weist FiveM an, die angegebene HTML-Datei zu verwenden (<code>Hauptseite</code> in unserem Fall) als Ladebildschirm des Spiels.</li> <li><strong><code>Dateien { ... }</code></strong>: <strong>Sehr wichtig!</strong> Du musst <em>jede einzelne Datei</em> die deine HTML-Seite laden muss, relativ zum Stammverzeichnis des Ressourcenordners. Dazu gehören: <ul class="wp-block-list"> <li>Die HTML-Datei selbst (<code>Hauptseite</code>)</li> <li>Die CSS-Datei (<code>Stil.css</code>)</li> <li>Die JavaScript-Datei (<code>script.js</code>)</li> <li>Alle Bilder (z. B. <code>Bilder/Logo.png</code>, <code>Bilder/Hintergrund.jpg</code>)</li> <li>Alle Audiodateien (z. B. <code>audio/hintergrundmusik.ogg</code>)</li> <li>Alle benutzerdefinierten Schriftarten, die du in deinem CSS verknüpft haben könntest.</li> <li><em>Wenn du hier eine Datei vergisst, wird sie nicht im Spiel geladen!</em></li> </ul> </li> <li><strong><code>Client_Skript „client.lua“</code></strong>: Wir schließen dies ein, weil wir im nächsten Schritt ein kleines Client-Skript erstellen, um das Ausblenden der standardmäßigen FiveM-Ladeelemente zu handhaben.</li> <li><strong><code>server_script 'server.lua'</code></strong>: Wird nur für fortgeschrittene Szenarien benötigt, in denen Ihr Ladebildschirm mit dem Server kommunizieren muss (z. B. zum Abrufen dynamischer Spielerzahlen <em>vor</em> die Hauptspielumgebung wird geladen, was komplex ist). Wir werden dies nicht für eine grundlegende Einrichtung verwenden.</li> <li><strong><code>nui_settings</code></strong>: Ermöglicht das Festlegen spezifischer Sicherheitsrichtlinien für den NUI-Rahmen. Normalerweise nicht nötig für Standard-Ladescreens, es sei denn, du bindest externen Inhalt ein oder arbeitest mit komplexen Interaktionen.</li> </ul> <p class="wp-block-paragraph">Speichere diese Datei als <code>fxmanifest.lua</code>.</p> <p class="wp-block-paragraph"><em>(Hinweis: Ältere Server verwenden möglicherweise <code>__resource.lua</code> anstatt <code>fxmanifest.lua</code>Die Syntax ist sehr ähnlich, aber <code>fx_version</code> wird normalerweise weggelassen oder ist anders, und die Anweisungen können leicht abweichen. <code>fxmanifest.lua</code> ist der moderne Standard).</em></p> <h2 class="wp-block-heading" id="step-5-disabling-the-default-five-m-bridge-animation-lua-client-lua">Schritt 5: Deaktivieren der Standard-FiveM-Bridge-Animation (Lua – <code>client.lua</code>)</h2> <p class="wp-block-paragraph">Standardmäßig zeigt FiveM einen eigenen Ladetext und manchmal eine „Brücken“-Ladeanimation an <em>vor</em> Ihr benutzerdefinierter Bildschirm übernimmt die volle Kontrolle. Wir können diese mithilfe eines clientseitigen Lua-Skripts für ein übersichtlicheres Erscheinungsbild ausblenden.</p> <div class="wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex"> <div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-white-color has-black-background-color has-text-color has-background has-link-color wp-element-button" href="https://fivemx.com/de/bruckenelement-im-fivem-ladebildschirm-deaktivieren/">Brückenanimation deaktivieren</a></div> </div> <p class="wp-block-paragraph">Erstelle eine Datei mit dem Namen <code>client.lua</code> in deinem <code>mein-Ladebildschirm</code> Ordner.</p> <pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">-- client.lua für die Ladebildschirm-Ressource -- Dieser Code wird ausgeführt, sobald die Ressource auf dem Client startet -- Wir warten einen kurzen Moment, um sicherzustellen, dass NUI wahrscheinlich bereit ist Citizen.Wait(100) -- Methode 1: Verwendung von ShutdownLoadingScreenNui (Empfohlen zum einfachen Verstecken) -- Dies versucht, die Standard-FiveM-Lade-GUI-Elemente sofort zu verstecken. -- Es ist oft effektiv, aber die Timing kann manchmal schwierig sein, je nach Client-Ladegeschwindigkeit. ShutdownLoadingScreenNui() -- Du kannst auch eine Nachricht an deine NUI-Seite senden, falls benötigt, zum Beispiel, -- um zu signalisieren, dass Lua bereit ist oder initiale Daten zu übergeben. -- SendNUIMessage({ -- type = "luaReady", -- message = "Client-Skript wurde geladen!" -- }) -- Methode 2: Kontrolliertes Verstecken mit CreateThread und AddTextEntry -- Diese Methode überschreibt kontinuierlich die Standard-Ladetexteinträge. -- Sie kann zuverlässiger sein, um zu gewährleisten, dass der Standardtext nicht kurz aufblitzt. -- Entkommentiere diesen Abschnitt und kommentiere ShutdownLoadingScreenNui() aus, wenn du diese Methode bevorzugst. --[[ Citizen.CreateThread(function() -- Verstecke die Standard-"Initialisierung..."-Textkomponenten AddTextEntry('FE_THDR_GTAO', ' ') -- Online laden AddTextEntry('PM_NAME_APP', ' ') -- FiveM-Anwendungsname (kann variieren) AddTextEntry('PM_INFO_DET', ' ') -- Build-Info / Verbindungsstatus AddTextEntry('LOADING_SPLAYER_L', ' ') -- Story-Modus laden (erscheint manchmal) AddTextEntry('DLC_ITEM_UNLOCK', ' ') -- offene Nachrichten, falls vorhanden -- Überschreibe sie weiterhin periodisch, während der benutzerdefinierte Bildschirm aktiv sein soll -- Diese Schleife könnte übertrieben sein; oft reicht es, sie einmal zu setzen. -- Passe die Wartezeit an oder entferne die Schleife, wenn die Leistung beeinträchtigt wird. while true do Citizen.Wait(500) -- Überprüfe/Überschreibe alle 500ms -- Überprüfe, ob der Ladebildschirm noch aktiv ist (Pseudocode, benötigt tatsächliche Logik) -- local isLoading = GetIsLoadingScreenActive() -- Dieser Native könnte früh genug nicht funktionieren -- if not isLoading then break end -- Schleife verlassen, wenn das Hauptspiel geladen wird (benötigt bessere Bedingung) -- Wende die Überschreibungen erneut an, nur für den Fall AddTextEntry('FE_THDR_GTAO', ' ') AddTextEntry('PM_NAME_APP', ' ') AddTextEntry('PM_INFO_DET', ' ') AddTextEntry('LOADING_SPLAYER_L', ' ') AddTextEntry('DLC_ITEM_UNLOCK', ' ') -- Optional, verstecke den rotierenden Ladekreis in der unteren rechten Ecke HideHudComponentThisFrame(14) -- HUD_LOADING_SPINNER end end) --]] -- Du kannst hier weitere Logik hinzufügen, falls benötigt, zum Beispiel das Hören auf Spielevents -- um spezifische Nachrichten an deinen NUI-Ladebildschirm zu senden. -- Beispiel: Sende eine Nachricht, wenn der Spieler spawn (obwohl der Ladebildschirm normalerweise dann bereits weg ist) -- AddEventHandler('playerSpawned', function() -- SendNUIMessage({ type = 'playerReady' }) -- end) print('[MyLoadingScreen] Client-Skript geladen.')</pre> <p class="wp-block-paragraph"><strong>Erläuterung:</strong></p> <ul class="wp-block-list"> <li><strong><code>Bürger.Warten(100)</code></strong>: Eine kleine Verzögerung. Manchmal versucht der Versuch, mit NUI oder Spielelementen zu interagieren <em>sofort</em> Wenn das Laden des Skripts fehlschlägt, kann dies passieren. Dies gibt den Dingen einen Moment Zeit zum Initialisieren.</li> <li><strong><code>ShutdownLoadingScreenNui()</code></strong>: Dies ist eine integrierte native FiveM-Funktion, die speziell dafür entwickelt wurde, die vom Spiel/FiveM selbst bereitgestellten Standard-UI-Elemente des Ladebildschirms auszublenden. Dies ist normalerweise der einfachste und direkteste Weg.</li> <li><strong><code>SendNUIMessage({ ... })</code></strong>: Ein Beispiel, das zeigt, wie du Daten senden kannst <em>aus</em> Lua <em>Zu</em> dein JavaScript. Die Tabelle, die du übergibst, wird zu <code>Ereignisdaten</code> Objekts in deinem <code>window.addEventListener('Nachricht', ...)</code> Zuhörer in <code>script.js</code>. Du könntest dies verwenden, um spezifische Aktionen auszulösen oder Serverinformationen zu übergeben.</li> <li><strong>Methode 2 (auskommentiert):</strong> <ul class="wp-block-list"> <li>Bietet einen alternativen Ansatz mit <code>Texteintrag hinzufügen</code>. Diese Funktion ermöglicht es dir, Standard-Spieltextzeilen zu überschreiben, die durch ihre Schlüssel identifiziert werden (wie <code>FE_THDR_GTAO</code>). Indem du sie auf ein Leerzeichen (‘ ‘) setzt, blendest du sie effektiv aus.</li> <li>Der <code>Bürger.CreateThread</code> erstellt einen separaten Thread für diese Aufgabe.</li> <li>Der <code>während wahr</code> Schleife (mit <code>Bürger.Warten</code>) wendet diese Überschreibungen kontinuierlich an. Dies kann zuverlässiger gegen das Spiel sein, das den Text zurücksetzen versucht, könnte aber übertrieben sein. Es enthält auch <code>HideHudComponentThisFrame(14)</code> um den Spinner auszublenden.</li> <li><strong>Auswählen <em>eins</em> Verfahren.</strong> Verwenden von <code>ShutdownLoadingScreenNui()</code> wird im Allgemeinen aus Gründen der Einfachheit bevorzugt, es sei denn, du hast Probleme, bei denen Standard-Elemente kurz aufblitzen.</li> </ul> </li> <li><strong><code>drucken(...)</code></strong>: Protokolliert eine Nachricht in der F8-Konsole des Clients, nützlich zur Bestätigung des geladenen Skripts.</li> </ul> <p class="wp-block-paragraph">Speichere diese Datei als <code>client.lua</code>.</p> <h2 class="wp-block-heading" id="step-6-installing-and-running-the-loading-screen">Schritt 6: Installieren und Ausführen des Ladebildschirms</h2> <p class="wp-block-paragraph">Nachdem nun alle Teile erstellt sind, legen wir sie auf dem Server ab.</p> <ol class="wp-block-list"> <li><strong>Ressource hochladen:</strong> <ul class="wp-block-list"> <li>Nimm das Ganze <code>mein-Ladebildschirm</code> Ordner (der jetzt enthält <code>Hauptseite</code>, <code>Stil.css</code>, <code>script.js</code>, <code>fxmanifest.lua</code>, <code>client.lua</code>und die <code>Bilder</code> Und <code>Audio-</code> Unterordner mit ihrem Inhalt).</li> <li>Lade diesen vollständigen Ordner auf deinen FiveM-Server hoch. <code>Ressourcen</code> Verzeichnis. Du könntest FTP-Software (wie FileZilla) oder das Web-Panel deines Server-Hosts verwenden. Die Struktur sollte so aussehen: <code>[Serverdaten]/Ressourcen/Mein Ladebildschirm/</code>.</li> </ul> </li> <li><strong>Stelle sicher, dass die Ressource in <code>server.cfg</code>:</strong> <ul class="wp-block-list"> <li>Öffne die Hauptkonfigurationsdatei deines Servers, die normalerweise <code>server.cfg</code>.</li> <li>Finde den Abschnitt, in dem die Ressourcen gestartet werden (Zeilen, die normalerweise mit <code>sicherstellen</code> oder <code>Start</code>).</li> <li>Füge eine Zeile hinzu, um deine Ladebildschirm-Ressource zu starten:<br><code>cfg # Benutzerdefinierter Ladebildschirm stellt sicher, dass mein Ladebildschirm</code></li> <li><strong>Die Platzierung spielt eine kleine Rolle:</strong> Stelle sicher, dass es aufgelistet ist <em>vor</em> Ressourcen, deren Laden möglicherweise lange dauert, wenn der Bildschirm so früh wie möglich angezeigt werden soll. Grundlegende <code>sicherstellen</code> ist in der Regel ausreichend. <em>nicht</em> setze es in irgendetwas ein <code>[Kategorie]</code> Klammern, wenn es eine Standardressource sein soll.</li> </ul> </li> <li><strong>Starte deinen Server neu:</strong> Für die Änderungen in <code>server.cfg</code> und damit die neue Ressource erkannt wird, musst du deinen FiveM-Server vollständig neu starten.</li> <li><strong>Anschließen und testen:</strong> Starte FiveM und verbinde dich mit deinem Server. Du solltest nun deinen benutzerdefinierten Ladebildschirm anstelle des Standardbildschirms sehen! Teste den Fortschrittsbalken (er sollte auf den tatsächlichen FiveM-Ladevorgang reagieren), die wechselnden Nachrichten und die Musiksteuerung. Überprüfe die F8-Konsole im Spiel auf Fehler von deinem <code>client.lua</code> oder potenzielle NUI-Probleme. Überprüfe die Browserkonsole (oft über F8 -> NUI-Tools zugänglich oder durch direktes Öffnen des HTML) auf JavaScript-Fehler.</li> </ol> <h2 class="wp-block-heading" id="advanced-customization-ideas">Erweiterte Anpassungsideen</h2> <p class="wp-block-paragraph">Sobald du die Grundlagen funktionierend hast, kannst du fortgeschrittenere Funktionen erkunden:</p> <ul class="wp-block-list"> <li><strong>Hintergrundvideos:</strong> Statt eines statischen Bildes, verwende ein HTML <code><video></code> Etikett. <ul class="wp-block-list"> <li>Hinzufügen <code><video autoplay muted loop id="bg-video"></video></code> zu deinem <code>Hauptseite</code>.</li> <li>Stil <code>#bg-Video</code> in CSS ähnlich dem <code>.Hintergrund</code> div (absolute Position, 100% Breite/Höhe, <code>Objekt-Fit: Abdeckung</code>, <code>z-Index: -1</code>).</li> <li><strong>Wichtig:</strong> Videos erhöhen den Ladebildschirm deutlich in der Größe. Optimieren sie stark (Auflösung, Bitrate). Verwende Formate wie <code>.mp4</code> (H.264-Codec). Vergiss nicht, die Videodatei zur <code>fxmanifest.lua</code>. Autoplay erfordert möglicherweise <code>stummgeschaltet</code> Attribut zunächst aufgrund von Browserrichtlinien; du könntest JS benötigen, um basierend auf der Benutzerinteraktion (wie Klicken auf die Lautstärkensteuerung) zu entsperren.</li> </ul> </li> <li><strong>Serverregeln/-nachrichten dynamisch abrufen:</strong> Statt Nachrichten in JS hart zu codieren, verwende <code>bringen</code> in deinem <code>script.js</code> um Regeln oder Ankündigungen von einem <code>.json</code> Datei innerhalb deiner Ressource oder sogar von einem externen Webserver/API hinzuzufügen. Dies macht Updates einfacher.</li> <li><strong>Verwenden von Web-Frameworks:</strong> Nutze CSS-Frameworks wie Tailwind CSS oder Bootstrap für schnelleres Styling oder JavaScript-Frameworks wie Vue.js oder React für komplexere UI-Logik (allerdings erhöht das die Komplexität und die Build-Schritte erheblich).</li> <li><strong>API-Integrationen:</strong> Hole Daten von externen APIs ab (z. B. zeige die Online-Spielerzahl von deinem Discord-Server mit einem Discord-Bot und einem einfachen API-Endpunkt). Dies erfordert serverseitiges Skripting (<code>server.lua</code> in deiner Ressource oder einem separaten Webdienst) um sicher zu verwalten.</li> <li><strong>Anspruchsvollere Animationen:</strong> Verwende CSS-Animationen (<code>@Schlüsselbilder</code>) oder JavaScript-Animationsbibliotheken (wie GSAP) für weichere Übergänge, Überblendeffekte oder animierte Logos.</li> </ul> <h2 class="wp-block-heading" id="troubleshooting-common-issues">Fehlerbehebung bei allgemeinen Problemen</h2> <ul class="wp-block-list"> <li><strong>Der Ladebildschirm wird nicht angezeigt:</strong> <ul class="wp-block-list"> <li>Überprüfen <code>server.cfg</code>: Ist <code>stelle sicher, dass my-loading-screen</code> vorhanden und richtig geschrieben? Gibt es beim Start in der Serverkonsole Fehler im Zusammenhang mit der Ressource?</li> <li>Überprüfen <code>fxmanifest.lua</code>: Ist die <code>Ladebildschirm „index.html“</code> Zeile korrekt? Sind <em>alle</em> notwendigen Dateien (HTML, CSS, JS, Bilder, Audio) aufgelistet in der <code>Dateien</code> Block? Überprüfe Dateinamen und Pfade sorgfältig (Groß-/Kleinschreibung auf Linux!).</li> <li>Ordnerstruktur prüfen: Ist die <code>mein-Ladebildschirm</code> Ordner direkt im <code>Ressourcen</code> Ordner?</li> </ul> </li> <li><strong>Nicht angewendete CSS-Stile:</strong> <ul class="wp-block-list"> <li>HTML prüfen <code></code> Tag: Ist die <code>href="style.css"</code> richtig?</li> <li>Überprüfen <code>fxmanifest.lua</code>: Ist <code>Stil.css</code> aufgeführt in der <code>Dateien</code> Block?</li> <li>Überprüfe die CSS-Syntax: Gibt es Tippfehler oder Fehler in deinem <code>Stil.css</code> Datei? Verwende einen CSS-Validator.</li> <li>Browser-Cache: Manchmal hält der FiveM-NUI-Cache alte Versionen fest. Leere deinen FiveM-Cache (meistens in <code>%localappdata%FiveMFiveM.appcache</code> auf Windows, lösche Ordner wie <code>Browser</code>, <code>db</code>, <code>nui-Speicher</code>) und starte FiveM neu.</li> </ul> </li> <li><strong>JavaScript funktioniert nicht (kein Fortschritt, keine Nachrichtenänderungen, keine Musik):</strong> <ul class="wp-block-list"> <li>HTML prüfen <code></code> Tag: Ist die <code>src="script.js"</code> richtig und platziert an der <em>Ende</em> der <code><body></code>?</li> <li>Überprüfen <code>fxmanifest.lua</code>: Ist <code>script.js</code> aufgeführt in der <code>Dateien</code> Block?</li> <li>Überprüfe die Browser-Konsole: Öffne die F8-Konsole in FiveM, gehe zu NUI Devtools (falls verfügbar) oder öffne die <code>Hauptseite</code> direkt in einem Browser und überprüfe die Entwicklerkonsole (meistens F12) auf JavaScript-Fehler. Diese Fehler zeigen oft die genaue Problemzeile an.</li> <li>Audioprobleme: Ist die Musikdatei in <code>.ogg</code> Format? Ist der Pfad in <code>neues Audio(...)</code> richtig? Ist <code>audio/deine_musik.ogg</code> im Manifest aufgeführt? Denke an die Autoplay-Einschränkungen des Browsers – die Musik könnte erst nach dem Klicken auf die Abspieltaste starten.</li> </ul> </li> <li><strong>Fortschrittsbalken wird nicht aktualisiert:</strong> <ul class="wp-block-list"> <li>Brauchst du die FiveM NUI-Ereignisse (<code>window.addEventListener('Nachricht', ...)</code>? Stelle sicher, dass dieser Code aktiv ist (nicht auskommentiert).</li> <li>Sind die Ereignisnamen (<code>Ladestatus</code>, <code>Fortschritt</code>, <code>Lastfraktion</code>) richtig? Diese können manchmal zwischen FiveM-Updates oder bestimmten Spielversionen leicht variieren. Hinzufügen <code>console.log(JSON.stringify(Ereignisdaten))</code> im Nachrichtenlistener, um genau zu sehen, welche Daten FiveM sendet.</li> <li>Ist die Element-ID (<code>Fortschrittsbalken-innen</code>) sowohl in HTML als auch in JS korrekt?</li> </ul> </li> <li><strong>Standardmäßige FiveM-Ladeelemente sind weiterhin sichtbar:</strong> <ul class="wp-block-list"> <li>Überprüfen <code>client.lua</code>: Läuft das Skript (überprüfe den <code>drucken</code> Meldung in F8)? Ist <code>ShutdownLoadingScreenNui()</code> wird aufgerufen? Falls du <code>Texteintrag hinzufügen</code>, sind die Tasten für deinen Spielbuild korrekt? Versuche, den Anfangswert zu erhöhen <code>Bürger.Warten()</code>.</li> </ul> </li> </ul> <h2 class="wp-block-heading" id="need-a-premium-solution-check-out-five-mx">Brauchst du eine Premium-Lösung? Schau dir FiveMX an!</h2> <p class="wp-block-paragraph">Ein Ladebildschirm von Grund auf zu erstellen ist lohnend, kann aber auch zeitaufwendig sein, besonders wenn du fortgeschrittene Funktionen und ein hochpoliertes Design möchtest.</p> <p class="wp-block-paragraph">Wenn du eine fertige, professionelle Lösung bevorzugst, haben wir hier bei FiveMX etwas für dich.</p> <p class="wp-block-paragraph">Wir bieten eine kuratierte Auswahl hochwertiger, funktionsreicher Ladebildschirme, die von erfahrenen Entwicklern entworfen wurden.</p> <p class="wp-block-paragraph"><strong>Vorteile der kostenpflichtigen Ladebildschirme von FiveMX:</strong></p> <ul class="wp-block-list"> <li><strong>Professionelle Designs:</strong> Optisch beeindruckende und moderne Ästhetik.</li> <li><strong>Erweiterte Funktionen:</strong> Enthalten sind oft Hintergrundvideos, Musikplayer, mehrere konfigurierbare Abschnitte, Vorschauen der Discord-Integration, Serverstatusanzeigen und mehr.</li> <li><strong>Einfache Konfiguration:</strong> Typischerweise kommen sie mit einfachen Konfigurationsdateien, um Text, Logos, Links und Funktionen anzupassen, ohne tiefe Code-Änderungen vornehmen zu müssen.</li> <li><strong>Zuverlässigkeit und Support:</strong> Auf Kompatibilität getestet und oft mit Entwicklersupport, falls Probleme auftreten.</li> <li><strong>Spar Zeit & Mühe:</strong> Erhalte sofort ein detailliertes Ergebnis, sodass du dich auf andere Aspekte deines Servers konzentrieren kannst.</li> </ul> <p class="wp-block-paragraph">Entdecke unsere Auswahl an Schnittstellen und Ladebildschirmen, um die perfekte Passform für die Identität deines Servers zu finden:</p> <ul class="wp-block-list"> <li>FiveMX-Ladebildschirme Kategorie</li> <li>FiveMX-Skriptsammlung (der Abschnitt „Schnittstellen“ enthält oft Ladebildschirme)</li> </ul> <p class="wp-block-paragraph">Überlege dir diese beliebten Optionen, die auf FiveMX verfügbar sind:</p> <ol class="wp-block-list"> <li><strong>Moderner Ladebildschirm V1</strong>: Eine elegante und saubere Option für den Einstieg.</li> <li><strong>Erweiterter Ladebildschirm V6</strong>: Vollgepackt mit Funktionen für die ultimative Anpassung.</li> <li><strong>Einzigartiger Ladebildschirm V13</strong>– Hebe die Einrichtung mit einem einzigartigen Design hervor.</li> <li><strong>Ladebildschirm V16</strong>: Eine weitere ausgezeichnete Wahl mit modernen Funktionen.</li> </ol> <p class="wp-block-paragraph">Die Investition in einen Premium-Ladebildschirm kann die wahrgenommene Qualität und das Spielerlebnis deines Servers erheblich beeinflussen – schon beim ersten Klick.</p> <h2 class="wp-block-heading" id="conclusion">Abschluss</h2> <p class="wp-block-paragraph">Erstellen eines <strong>Benutzerdefinierter FiveM-Ladebildschirm</strong> ist eine leistungsstarke Möglichkeit, die Server-Identität zu verbessern und eine bessere Benutzererfahrung zu bieten.</p> <p class="wp-block-paragraph">Wir haben die Einrichtung der HTML-Struktur, das Stylen mit CSS, das Hinzufügen dynamischen Verhaltens mit JavaScript und die Integration in FiveM mithilfe der <code>fxmanifest.lua</code> und eine einfache <code>client.lua</code> Skript zum Ausblenden von Standardelementen.</p> <p class="wp-block-paragraph">Denke daran, dass der Schlüssel eine sorgfältige Dateiverwaltung (alles im Manifest auflisten), das Verständnis, wie NUI-Ereignisse für echte Fortschrittsaktualisierungen funktionieren, und die Verwendung von Web-Standards (HTML, CSS, JS) ist.</p> <p class="wp-block-paragraph">Habe keine Angst, mit verschiedenen Stilen, Nachrichten und Medien zu experimentieren.</p> <p class="wp-block-paragraph">Teste gründlich in deinem Browser und im Spiel, verwende die Entwicklerkonsolen, um Probleme zu beheben.</p> <p class="wp-block-paragraph">Egal, ob du dein eigenes Meisterwerk nach dieser Anleitung baust oder eine polierte Premium-Option von FiveMX.com wählst, in deinen Ladebildschirm zu investieren bedeutet, in den ersten Eindruck deines Servers zu investieren.</p> <p class="wp-block-paragraph">Viel Spaß beim Codieren, und wir hoffen, dass dir das hilft, einen tollen Einstiegspunkt für deine Spieler zu erstellen!</p> <h2 class="wp-block-heading" id="frequently-asked-questions-faq">Häufig gestellte Fragen (FAQ)</h2> <p class="wp-block-paragraph"><strong>F1: Kann ich Hintergrundvideos anstelle von Bildern verwenden?</strong></p> <p class="wp-block-paragraph">A: Ja! Nutze das HTML <code><video></code> Etikett (<code><video autoplay muted loop id="bg-video"></video></code>). Style es mit CSS, um den Bildschirm abzudecken (<code>Position: absolut</code>, <code>Breite: 100%</code>, <code>Höhe: 100%</code>, <code>Objekt-Fit: Abdeckung</code>, <code>z-Index: -1</code>Denk daran <code>stumm</code> damit Autoplay zuverlässig funktioniert, optimiere die Videodateigröße stark, nutze kompatible Formate wie MP4 (H.264) und liste die Videodatei in deiner <code>fxmanifest.lua</code>.</p> <p class="wp-block-paragraph"><strong>F2: Wie kann ich dafür sorgen, dass der Fortschrittsbalken Folgendes anzeigt: <em>tatsächlich</em> Ladefortschritt von FiveM?</strong></p> <p class="wp-block-paragraph">A: Der zuverlässigste Weg ist die Verwendung von JavaScript <code>window.addEventListener('Nachricht', ...)</code> um auf NUI-Nachrichten zu hören, die von FiveM gesendet werden. Suche speziell nach einem Ereignis wie <code>Fortschritt</code> die oft enthält eine <code>Lastfraktion</code> Eigenschaft (ein Wert von 0,0 bis 1,0). Multipliziere dies mit 100 und gib es an deinen <code>Aktualisierungsfortschritt</code> JavaScript-Funktion auf. Verlasse dich nicht nur auf simulierten Fortschritt wie den <code>Intervall festlegen</code> Beispiel) für die endgültige Version.</p> <p class="wp-block-paragraph"><strong>F3: Wo genau lege ich die Ladebildschirmdateien auf meinem Server ab?</strong></p> <p class="wp-block-paragraph">A: Erstelle einen dedizierten Ordner für deine Ressource (z. B., <code>mein-Ladebildschirm</code>) im Haupt- <code>Ressourcen</code> Verzeichnis. Alle Dateien (<code>Hauptseite</code>, <code>Stil.css</code>, <code>script.js</code>, <code>fxmanifest.lua</code>, <code>client.lua</code>und Unterordner wie <code>Bilder</code>, <code>Audio-</code>) sollte in diesen Ressourcenordner gehen.</p> <p class="wp-block-paragraph"><strong>F4: Kann ich Hintergrundmusik haben? Wie füge ich Steuerelemente hinzu?</strong></p> <p class="wp-block-paragraph">A: Ja. Verwende das HTML <code><audio></code> Tag oder erstelle einen <code>Audio</code> Objekt in JavaScript (<code>neues Audio('audio/musik.ogg')</code>). <strong>Wichtig, verwende das <code>.ogg</code> Audioformat</strong> für die beste Kompatibilität in FiveM NUI. Füge Standard-HTML-Schaltflächen hinzu (<code><button></code>) und möglicherweise eine Bereichseingabe (<code></code>) für das Volumen <code>Hauptseite</code>. Verwende JavaScript-Event-Listener (<code>Ereignislistener hinzufügen</code>) auf diesen Elementen, um die Audio-Objekte zu steuern <code>.spielen()</code>, <code>.Pause()</code>, Und <code>.Volumen</code> Eigenschaften. Vergiss nicht, die Audiodatei in deinem Manifest aufzulisten.</p> <p class="wp-block-paragraph"><strong>F5: Warum wird mein Ladebildschirm überhaupt nicht angezeigt?</strong></p> <p class="wp-block-paragraph">A: Überprüfe diese häufigen Ursachen:<br>1. Ist die Ressource korrekt gesichert in <code>server.cfg</code> (<code>Stelle sicher, dass resource_folder_name</code>)?<br>2. Ist die <code>fxmanifest.lua</code> im Ressourcenordner vorhanden?<br>3. Enthält das Manifest die <code>loadscreen 'dein_html_file.html'</code> Linie?<br>4. Sind <em>alle</em> erforderliche Dateien (HTML, CSS, JS, Bilder, Audio, Schriftarten) genau aufgelistet unter <code>Dateien { ... }</code> im Manifest aufgeführt ist? Überprüfe die Pfade und Dateinamen (Groß-/Kleinschreibung beachten!).<br>5. Liegen in der Serverkonsole oder der Client-F8-Konsole Fehler vor, die darauf zurückzuführen sind, dass die Ressource nicht geladen werden konnte?<br>6. Hast du den Server nach dem Hinzufügen der Ressource und der Sicherstellung neu gestartet?</p> <p class="wp-block-paragraph"><strong>F6: Wie kann ich dafür sorgen, dass der Ladebildschirm beim Start des Spiels sanft ausgeblendet wird?</strong></p> <p class="wp-block-paragraph">A: Dies erfordert Kommunikation zwischen deinem Lua-Skript und der NUI-Seite. FiveM hat kein perfekt zuverlässiges “Laden vollständig abgeschlossen, kurz vor dem Spawn”-Ereignis, das leicht zu erfassen ist <em>vor</em> wird der NUI zerstört. Du könntest jedoch:<br>1. Sende eine benutzerdefinierte NUI-Nachricht (<code>SendNUIMessage({ Typ = 'loadingAlmostDone' })</code>) aus einem Client-Lua-Skript basierend auf bestimmten Spielereignissen oder Timern kurz vor dem Spawn.<br>2. In deinem JavaScript, höre auf diese Nachricht (<code>wenn (event.data.type === 'loadingAlmostDone')</code>).<br>3. Wenn empfangen, löse eine CSS-Fade-out-Animation auf deinem Hauptcontainer aus (<code>.loading-container.fade-out { Deckkraft: 0; Übergang: Deckkraft 1s Ausblenden; }</code> und füge den <code>Ausblenden</code> Klasse mit JS). Dies ermöglicht einen visuellen Übergang, obwohl die NUI danach möglicherweise immer noch abrupt von FiveM entfernt wird.</p> <h2 class="wp-block-heading" id="p">Kostenpflichtige Ladebildschirme</h2> <div data-wp-context="{"notices":[],"hideNextPreviousButtons":false,"isDisabledPrevious":true,"isDisabledNext":false,"ariaLabelPrevious":"Vorherige Produkte","ariaLabelNext":"N\u00e4chste Produkte"}" data-wp-init="callbacks.onRender" data-wp-interactive="woocommerce/product-collection" data-wp-router-region="wc-product-collection-0" data-__private-preview-state="{"isPreview":false,"previewMessage":"Actual products will vary depending on the page being viewed."}" data-block-name="woocommerce/product-collection" data-dimensions="{"widthType":"fill"}" data-display-layout="{"type":"flex","columns":3,"shrinkColumns":true}" data-query-context-includes="["collection"]" data-query-id="0" data-query="{"perPage":9,"pages":0,"offset":0,"postType":"product","order":"asc","orderBy":"title","search":"","exclude":[],"inherit":false,"taxQuery":{"product_cat":[537]},"isProductCollectionBlock":true,"featured":false,"woocommerceOnSale":false,"woocommerceStockStatus":["instock","onbackorder"],"woocommerceAttributes":[],"woocommerceHandPickedProducts":[],"filterable":true,"relatedBy":{"categories":true,"tags":true}}" data-tag-name="div" class="wp-block-woocommerce-product-collection is-layout-flow wp-block-woocommerce-product-collection-is-layout-flow"> <div data-wp-interactive="woocommerce/store-notices" class="wc-block-components-notices alignwide"> <template data-wp-each--notice="state.notices" data-wp-each-key="context.notice.id"> <div class="wc-block-components-notice-banner" data-wp-init="callbacks.scrollIntoView" data-wp-class--is-error="state.isError" data-wp-class--is-success="state.isSuccess" data-wp-class--is-info="state.isInfo" data-wp-class--is-dismissible="context.notice.dismissible" data-wp-bind--role="state.role" data-wp-watch="callbacks.injectIcon" > <div class="wc-block-components-notice-banner__content"> <span data-wp-init="callbacks.renderNoticeContent" aria-live="assertive" aria-atomic="true"></span> </div> <button data-wp-bind--hidden="!context.notice.dismissible" class="wc-block-components-button wp-element-button wc-block-components-notice-banner__dismiss contained" aria-label="Diesen Hinweis verwerfen" data-wp-on--click="actions.removeNotice" data-no-translation-aria-label="" > <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"> <path d="M13 11.8l6.1-6.3-1-1-6.1 6.2-6.1-6.2-1 1 6.1 6.3-6.5 6.7 1 1 6.5-6.6 6.5 6.6 1-1z" /> </svg> </button> </div> </template> </div> <div data-block-name="woocommerce/product-collection-no-results" class="wp-block-woocommerce-product-collection-no-results"><div class="wp-block-group is-vertical is-content-justification-center is-layout-flex wp-container-core-group-is-layout-3c957fdc wp-block-group-is-layout-flex"> <p class="has-medium-font-size wp-block-paragraph"><strong>Keine Ergebnisse gefunden</strong></p> <p class="wp-block-paragraph">Du kannst es versuchen <a class="wc-link-clear-any-filters" href="https://fivemx.com/de/how-to-create-a-custom-fivem-loading-screen/">Filter zu entfernen</a> oder gehe zu unserem <a class="wc-link-stores-home" href="https://fivemx.com/de/">Shop-Startseite</a></p> </div></div></div> <hr class="wp-block-separator has-alpha-channel-opacity" /> <h3 class="wp-block-heading" id="f">Kostenlose Ladebildschirme</h3> <div class="wp-block-query is-layout-flow wp-block-query-is-layout-flow"></div> <hr class="wp-block-separator has-alpha-channel-opacity" /> <p class="wp-block-paragraph">Fertig! Fragen? Hinterlasse einen Kommentar.</p> <!-- fivemx-loading-screen-consolidation:2026-07-19 --> <section data-fivemx-content-consolidation="loading-screen-2026-07-19"> <h2>Behalte die Ladebildschirm-Assets leichtgewichtig</h2> <ul> <li>Komprimiere Hintergrundbilder und Audio, bevor du sie packst. Vermeide ein großes Autoplay-Video, es sei denn, es ist für das Design unerlässlich, denn jeder verbundene Spieler muss das Asset laden.</li> <li>Verwende Pfade relativ zum Ressourcenordner und passe die Dateinamen genau an. Überprüfe, ob jede von HTML, CSS und JavaScript referenzierte Datei im Ressourcenmanifest enthalten ist.</li> <li>Setze explizite Bildabmessungen, um Layout-Verschiebungen zu vermeiden, und entferne ungenutzte Schriftarten, Skripte und Medien. Verlasse dich nicht auf ein Remote-Asset, das den Bildschirm verzögern oder brechen kann, wenn der Host nicht verfügbar ist.</li> <li>Teste mit einem sauberen Client-Cache und einer gedrosselten Verbindung. Überprüfe die Client-Konsole auf fehlende Dateien, dann verbinde dich erneut nach einem Ressourcen-Neustart, bevor du die Änderung veröffentlichst.</li> </ul> </section> <!-- fivemx-internal-link-opportunity:2026-08-04:start --> <section class="fivemx-related-resources" data-fivemx-internal-link-opportunity="loading-screen"> <h2>Vergleiche einen fertigen Ladescreen</h2> <p>Wenn du lieber den benutzerdefinierten Build oben mit einer verpackten Option vergleichen möchtest, überprüfe die <a href="/de/codem-venice-ladebildschirm/">Venice Loading Screen</a>. Auf der Produktseite werden saisonale NUI-Themen und Charakterauswahl-Integration aufgelistet; überprüfe die erforderliche Kernressourcen- und Asset-Pack-Unterstützung auf der Staging-Umgebung.</p> </section> <!-- fivemx-internal-link-opportunity:2026-08-04:end --> </div><!-- .entry-content --> <aside class="entry-meta"> <div class="vcard author"> <div class="avatar"></div><div class="author-details"><a href="https://fivemx.com/de/author/fivem/" class="url fn" rel="author">Lukas</a>Ich bin Luke, ein Gamer und schreibe gerne über FiveM, GTA und Rollenspiele. Ich betreibe eine Rollenspiel-Community und habe etwa 10 Jahre Erfahrung in der Verwaltung von Servern.</div> </div> <div class="post-meta"> <div class="cat-links"> <div class="label" data-no-translation="" data-trp-gettext="">Posted in:</div><a href="https://fivemx.com/de/anleitungen/" rel="category tag">Tutorials und Anleitungen</a>, <a href="https://fivemx.com/de/lua-skripting/" rel="category tag">LUA-Skripting</a> </div> <div class="tags-links"> <div class="label" data-no-translation="" data-trp-gettext="">Tagged:</div><a href="https://fivemx.com/de/etikett/fivem-script/" rel="tag">fivem-Skript</a>, <a href="https://fivemx.com/de/etikett/laden/" rel="tag">Laden</a> </div> </div> </aside> <div class="shoptimizer-posts-prev-next"> <div class="previous-post"> <div class="title" data-no-translation="" data-trp-gettext="">Previous article</div> <a href="https://fivemx.com/de/wie-man-eine-fivem-fahrschule-grundet/" rel="prev">Wie man eine FiveM-Fahrschule erstellt</a> </div> <div class="next-post"> <div class="title" data-no-translation="" data-trp-gettext="">Next article</div> <a href="https://fivemx.com/de/fivem-monetarisierungs-tutorial/" rel="next">FiveM-Server-Monetarisierungsleitfaden</a> </div> </div> <section id="comments" class="comments-area" aria-label="Post Comments" data-no-translation-aria-label=""> <div id="respond" class="comment-respond"> <span id="reply-title" class="gamma comment-reply-title">Schreibe einen Kommentar <small><a rel="nofollow" id="cancel-comment-reply-link" href="/de/how-to-create-a-custom-fivem-loading-screen/#respond" style="display:none;" data-no-translation="" data-trp-gettext="">Antwort abbrechen</a></small></span><p class="must-log-in" data-no-translation="" data-trp-gettext="">Du musst <a href="https://fivemx.com/wp-login.php?redirect_to=https%3A%2F%2Ffivemx.com%2Fde%2Fso-erstellen-sie-einen-benutzerdefinierten-fivem-ladebildschirm%2F">angemeldet</a> sein, um einen Kommentar abzugeben.</p> </div><!-- #respond --> </section><!-- #comments --> </div><!-- #post-## --> </main><!-- #main --> </div><!-- #primary --> </div><!-- .col-full --> </div><!-- #content --> </div> <footer class="site-footer"> <div class="col-full"> <div id="text-5" class="widget widget_text"><span class="gamma widget-title">FiveMX</span> <div class="textwidget"><p>FiveM-Skripte, MLOs, Serverpakete und Tools mit klaren Produktdetails, sicherer Bezahlung und konto-basiertem Support.</p> <p><a href="https://fivemx.com/de/shop/">Shop durchsuchen</a> · <a href="https://fivemx.com/de/unterstutzung/">Support erhalten</a></p> </div> </div><div id="nav_menu-19" class="widget widget_nav_menu"><span class="gamma widget-title">Frameworks</span><div class="menu-fivemx-shop-frameworks-container"><ul id="menu-fivemx-shop-frameworks" class="menu"><li id="menu-item-208815" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-208815"><a href="https://fivemx.com/de/esx-skripte/">ESX</a></li> <li id="menu-item-208816" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-208816"><a href="https://fivemx.com/de/qbcore-skripte/">Abonnieren</a></li> <li id="menu-item-208817" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-208817"><a href="https://fivemx.com/de/qbox-skripte/">QBOX</a></li> <li id="menu-item-208818" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-208818"><a href="https://fivemx.com/de/standalone-skripte/">Standalone</a></li> </ul></div></div><div id="nav_menu-20" class="widget widget_nav_menu"><span class="gamma widget-title">Kategorien</span><div class="menu-fivemx-shop-categories-container"><ul id="menu-fivemx-shop-categories" class="menu"><li id="menu-item-208293" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-208293"><a href="https://fivemx.com/de/polizei-skripte/">Polizei</a></li> <li id="menu-item-208296" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-208296"><a href="https://fivemx.com/de/fivem-job-skripte/">Jobs</a></li> <li id="menu-item-208297" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-208297"><a href="https://fivemx.com/de/fivem-hud/">HUD</a></li> <li id="menu-item-208298" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-208298"><a href="https://fivemx.com/de/fivem-inventarskripte/">Inventar</a></li> <li id="menu-item-208299" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-208299"><a href="https://fivemx.com/de/fivem-mlos/">MLOs</a></li> <li id="menu-item-208300" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-208300"><a href="https://fivemx.com/de/fivem-autos/">Fahrzeuge</a></li> <li id="menu-item-208301" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-208301"><a href="https://fivemx.com/de/fivem-serverpakete/">Server-Pakete</a></li> </ul></div></div><div id="nav_menu-10" class="widget widget_nav_menu"><span class="gamma widget-title">Hilfe & Rechtliches</span><div class="menu-footer-terms-container"><ul id="menu-footer-terms" class="menu"><li id="menu-item-808" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-808"><a href="https://fivemx.com/de/geschaftsbedingungen/">Geschäftsbedingungen</a></li> <li id="menu-item-810" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-810"><a href="https://fivemx.com/de/garantie/">Rückerstattung-Politik</a></li> <li id="menu-item-809" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-809"><a href="https://fivemx.com/de/datenschutzrichtlinie/">Datenschutzrichtlinie</a></li> <li id="menu-item-214468" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-214468"><a href="https://fivemx.com/de/um/">Über FiveMX<div class="icon-wrapper"> </div></a></li> <li id="menu-item-208589" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-208589"><a href="https://fivemx.com/de/kontakt/">Kontakt</a></li> </ul></div></div> </div> </footer> <footer class="copyright"> <div class="col-full"> <div id="custom_html-7" class="widget_text widget widget_custom_html"><div class="textwidget custom-html-widget">© 2026 FiveMX. Alle Rechte vorbehalten.</div></div> </div> </footer> </div><!-- #page --> <script id="fivemx-tawk-layout-stability"> (() => { const styleId = 'fivemx-tawk-emoji-layout'; const watched = new WeakSet(); let footerVisible = false; let purchaseControlsVisible = false; const extendedObserverRelease = Date.parse('2026-07-26T06:30:00Z'); const observerLifetime = Date.now() >= extendedObserverRelease ? 60000 : 15000; const mobilePurchaseViewport = window.matchMedia('(max-width: 1024px)'); const mobileStorefront = window.matchMedia('(max-width: 1024px)').matches && ( document.body.classList.contains('home') || document.body.classList.contains('single-product') || document.body.classList.contains('post-type-archive-product') || document.body.classList.contains('tax-product_cat') || document.body.classList.contains('tax-product_tag') ); const isTawkFrame = (frame) => { if (!(frame instanceof HTMLIFrameElement) || frame.parentElement?.parentElement !== document.body) { return false; } const layer = Number.parseInt(frame.style.zIndex || '0', 10); const fixed = frame.style.position === 'fixed'; const rootLayer = Number.parseInt( frame.parentElement.style.zIndex || window.getComputedStyle(frame.parentElement).zIndex || '0', 10 ); const fixedRoot = window.getComputedStyle(frame.parentElement).position === 'fixed'; if ((fixed && layer >= 1000002) || (fixedRoot && rootLayer >= 1000002)) { frame.parentElement.dataset.fivemxTawkRoot = 'true'; } return frame.parentElement.dataset.fivemxTawkRoot === 'true'; }; const syncChatVisibility = (frame) => { if (!isTawkFrame(frame)) return; const hideChat = document.body.classList.contains('drawer-open') || footerVisible || purchaseControlsVisible; const visibility = hideChat ? 'hidden' : 'visible'; const pointerEvents = hideChat ? 'none' : 'auto'; if ( frame.style.getPropertyValue('visibility') !== visibility || frame.style.getPropertyPriority('visibility') !== 'important' ) { frame.style.setProperty('visibility', visibility, 'important'); } if ( frame.style.getPropertyValue('pointer-events') !== pointerEvents || frame.style.getPropertyPriority('pointer-events') !== 'important' ) { frame.style.setProperty('pointer-events', pointerEvents, 'important'); } }; const patchFrame = (frame) => { const label = () => { if (isTawkFrame(frame) && !frame.hasAttribute('title')) { frame.setAttribute('title', 'FiveMX live chat'); } }; const suppressMobileAttentionGrabber = () => { if (!mobileStorefront || !isTawkFrame(frame)) return; const width = Number.parseFloat(frame.style.width || '0'); const height = Number.parseFloat(frame.style.height || '0'); const layer = Number.parseInt(frame.style.zIndex || '0', 10); const isAttentionImage = width === 124 && height === 95 && layer === 1000004; const isMessagePreview = width >= 300 && height >= 150 && height <= 400 && (frame.style.zIndex === '' || frame.style.zIndex === 'auto'); if ((isAttentionImage || isMessagePreview) && frame.style.display !== 'none') { frame.style.setProperty('display', 'none', 'important'); } }; label(); suppressMobileAttentionGrabber(); syncChatVisibility(frame); if (watched.has(frame)) return; watched.add(frame); const patch = () => { label(); suppressMobileAttentionGrabber(); try { const doc = frame.contentDocument; if (!doc || !doc.head) return false; if (doc.getElementById(styleId)) return true; const style = doc.createElement('style'); style.id = styleId; style.textContent = 'img.emojione{width:16px!important;height:16px!important;}'; doc.head.appendChild(style); return true; } catch (_) { return true; } }; patch(); frame.addEventListener('load', patch, { passive: true }); }; const inspect = (node) => { if (!(node instanceof Element)) return; if (node.matches('iframe')) patchFrame(node); node.querySelectorAll('iframe').forEach(patchFrame); }; document.querySelectorAll('iframe').forEach(patchFrame); const observer = new MutationObserver((records) => { records.forEach((record) => { if (record.type === 'attributes') { inspect(record.target); return; } record.addedNodes.forEach(inspect); }); }); observer.observe(document.documentElement, { attributes: true, attributeFilter: ['src', 'style'], childList: true, subtree: true, }); const drawerObserver = new MutationObserver(() => { document.querySelectorAll('iframe').forEach(syncChatVisibility); }); drawerObserver.observe(document.body, { attributes: true, attributeFilter: ['class'], }); const footer = document.querySelector('.site-footer'); if (footer && 'IntersectionObserver' in window) { const footerObserver = new IntersectionObserver((entries) => { footerVisible = entries.some((entry) => entry.isIntersecting); document.querySelectorAll('iframe').forEach(syncChatVisibility); }, { threshold: 0.01 }); footerObserver.observe(footer); } const purchaseControls = document.querySelectorAll( 'body.single-product .summary, body.woocommerce-cart .wc-proceed-to-checkout' ); if (purchaseControls.length && mobilePurchaseViewport.matches && 'IntersectionObserver' in window) { const visiblePurchaseControls = new Set(); const purchaseObserver = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { visiblePurchaseControls.add(entry.target); } else { visiblePurchaseControls.delete(entry.target); } }); purchaseControlsVisible = visiblePurchaseControls.size > 0; document.querySelectorAll('iframe').forEach(syncChatVisibility); }, { threshold: 0.01 }); purchaseControls.forEach((control) => purchaseObserver.observe(control)); } window.setTimeout(() => observer.disconnect(), observerLifetime); })(); </script> <template id="tp-language" data-tp-language="de_DE"></template><script type="speculationrules"> {"prefetch":[{"source":"document","where":{"and":[{"href_matches":"/de/*"},{"not":{"href_matches":["/wp-*.php","/wp-admin/*","/wp-content/uploads/*","/wp-content/*","/wp-content/plugins/*","/wp-content/themes/shoptimizer/*","/de/*\\?(.+)","/de/checkout/","/de/cart/"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]} </script> <input type="hidden" id="commercekit_nonce" name="commercekit_nonce" value="ea8e646b8e" /><input type="hidden" name="_wp_http_referer" value="/de/how-to-create-a-custom-fivem-loading-screen/" /><script type="text/javascript"> /* <![CDATA[ */ document.addEventListener( 'DOMContentLoaded', function() { var cgkit_nonce_ustate = 0; var cgkit_nonce_cvalue = Cookies.get( 'commercekit-nonce-value' ); var cgkit_nonce_cstate = Cookies.get( 'commercekit-nonce-state' ); var cgkit_user_switched = 0; var cgkit_fast_token = Cookies.get( 'commercekit-fast-token' ); cgkit_nonce_cvalue = cgkit_nonce_cvalue !== undefined ? cgkit_nonce_cvalue : ''; cgkit_fast_token = cgkit_fast_token !== undefined ? cgkit_fast_token : ''; if ( cgkit_nonce_cvalue == '' || cgkit_nonce_cstate != cgkit_nonce_ustate || cgkit_user_switched == 1 || ( cgkit_fast_token == '' && commercekit_ajs.fast_ajax_search !== undefined && commercekit_ajs.fast_ajax_search == 1 ) ) { var timestamp = new Date().getTime(); fetch( commercekit_ajs.ajax_url + '=commercekit_get_nonce&v=' + timestamp, { method: 'GET', } ).then( response => response.json() ).then( json => { if ( json.status == 1 ) { var twohrs = new Date( new Date().getTime() + 120 * 60 * 1000 ); if ( window.Cookiebot ) { /* Cookiebot compatible */ if ( window.Cookiebot.consent.preferences || window.Cookiebot.consent.statistics || window.Cookiebot.consent.marketing ) { Cookies.set( 'commercekit-nonce-value', json.nonce, { expires: twohrs } ); Cookies.set( 'commercekit-nonce-state', json.state, { expires: twohrs } ); if ( json.fast_token != '' ) { Cookies.set( 'commercekit-fast-token', json.fast_token, { expires: twohrs } ); } } else { Cookies.remove( 'commercekit-nonce-value' ); Cookies.remove( 'commercekit-nonce-state' ); Cookies.remove( 'commercekit-fast-token' ); } } else { Cookies.set( 'commercekit-nonce-value', json.nonce, { expires: twohrs } ); Cookies.set( 'commercekit-nonce-state', json.state, { expires: twohrs } ); if ( json.fast_token != '' ) { Cookies.set( 'commercekit-fast-token', json.fast_token, { expires: twohrs } ); } } cgkit_nonce_ustate = json.state; commercekit_update_nonce( json.nonce ); } } ); } else { commercekit_update_nonce( cgkit_nonce_cvalue ); } } ); function commercekit_update_nonce( nonce ) { var nonce_input = document.querySelector( '#commercekit_nonce' ); if ( nonce_input ) { nonce_input.value = nonce; } else { document.body.insertAdjacentHTML( 'beforeend', '<' + 'input type="hidden" id="commercekit_nonce" name="commercekit_nonce" value="' + nonce + '"' + '>' ); } commercekit_ajs.ajax_nonce = 1; if ( typeof cgkit_update_order_bump_views == 'function' ) { cgkit_update_order_bump_views(); } } /* ]]> */ </script> <script type="text/javascript"> /* <![CDATA[ */ var cgkit_wbmc = document.querySelector( '.wc-block-mini-cart' ); if ( cgkit_wbmc ) { var cgkitMCBCurrentRequest = null; var cgkitMCBCurrentCancel = null; function cgkitLoadMiniCartBlocks() { var cgkit_drawer = document.querySelector( '.wc-block-mini-cart__drawer' ); if ( ! cgkit_drawer ) { return; } clearTimeout( cgkitMCBCurrentRequest ); cgkitMCBCurrentRequest = setTimeout( function() { if ( cgkitMCBCurrentCancel ) { cgkitMCBCurrentCancel.abort(); } cgkitMCBCurrentCancel = new AbortController(); var timestamp = new Date().getTime(); fetch( commercekit_ajs.ajax_url + '=commercekit_mini_cart_blocks&v=' + timestamp, { signal: cgkitMCBCurrentCancel.signal, method: 'GET', } ).then( response => response.json() ).then( json => { if ( json.success ) { var cgkit_table = document.querySelector( '.wc-block-mini-cart__drawer .wc-block-mini-cart__items' ); var cgkit_before = document.querySelector( '#cgkit-before-mini-cart-blocks' ); if ( cgkit_before ) { cgkit_before.innerHTML = json.data.before_cart; } else if ( cgkit_table ) { cgkit_table.insertAdjacentHTML( 'afterbegin', '<div id="cgkit-before-mini-cart-blocks">' + json.data.before_cart + '</div>' ); } var cgkit_after = document.querySelector( '#cgkit-after-mini-cart-blocks' ); if ( cgkit_after ) { cgkit_after.innerHTML = json.data.after_cart; } else if ( cgkit_table ) { cgkit_table.insertAdjacentHTML( 'beforeend', '<div id="cgkit-after-mini-cart-blocks">' + json.data.after_cart + '</div>' ); } } } ).catch( function( e ) { } ); }, 100 ); } document.addEventListener( 'click', function( e ) { $this = e.target; $thisp = $this.closest( '.wc-block-mini-cart' ); if ( $this.classList.contains( 'wc-block-mini-cart' ) || $thisp ) { setTimeout( function() { cgkitLoadMiniCartBlocks(); }, 500 ); } } ); ( function() { const originalFetch = window.fetch; window.fetch = async function(...args) { const response = await originalFetch(...args); if ( args[0].includes( '/wc/store/v1/batch' ) || args[0].includes( '/wc/store/v1/cart' ) ) { cgkitLoadMiniCartBlocks(); } return response; }; } )(); } var cgkit_wbc = document.querySelector( '.wp-block-woocommerce-cart' ); if ( cgkit_wbc ) { var cgkit_wbc_timer = null; var cgkit_wbc_observer = new MutationObserver( function( mutations ) { clearTimeout( cgkit_wbc_timer ); cgkit_wbc_timer = setTimeout( function() { cgkit_update_wc_cart_block_fragments(); }, 100 ); } ); cgkit_wbc_observer.observe( cgkit_wbc, { childList: true, subtree: true} ); } function cgkit_update_wc_cart_block_fragments() { var ucfragment = new Event( 'wc_fragment_refresh' ); document.body.dispatchEvent( ucfragment ); } /* ]]> */ </script> <script type="text/javascript"> function commercekitOrderBumpAdd(product_id, obj, position){ var ajax_nonce = ''; var is_block_checkout = typeof window.cgkitBlockObpNonce !== 'undefined'; if ( is_block_checkout ) { ajax_nonce = window.cgkitBlockObpNonce; } else if ( commercekit_ajs.ajax_nonce != 1 ) { return true; } else { var nonce_input = document.querySelector( '#commercekit_nonce' ); if ( nonce_input ) { ajax_nonce = nonce_input.value; } } obj.setAttribute('disabled', 'disabled'); var wrap = obj.closest('.commercekit-order-bump-wrap'); if( wrap ){ var bullets = wrap.querySelector('.ckobp-bullets'); if( bullets ){ bullets.classList.add('processing'); } } var formData = new FormData(); formData.append('product_id', product_id); formData.append('commercekit_nonce', ajax_nonce); fetch( commercekit_ajs.ajax_url + '=commercekit_order_bump_add', { method: 'POST', body: formData, }).then(response => response.json()).then( json => { var ppp = document.querySelector('.paypalplus-paywall'); var wooccm = document.querySelectorAll('form.woocommerce-checkout .wooccm-field'); if ( is_block_checkout ) { if ( window.wp && window.wp.data ) { window.wp.data.dispatch('wc/store/cart').invalidateResolutionForStoreSelector('getCartData'); window.wp.data.dispatch('wc/store/cart').invalidateResolutionForStoreSelector('getCartTotals'); } if ( typeof window.cgkitRefreshBlockOrderBump === 'function' ) { window.cgkitRefreshBlockOrderBump( ajax_nonce ); } } else if ( ppp || wooccm.length > 0 ) { window.location.reload(); } else { var ucheckout = new Event('update_checkout'); document.body.dispatchEvent(ucheckout); var ufragment = new Event('wc_fragment_refresh'); document.body.dispatchEvent(ufragment); var cgkit_cart_drawer = document.querySelector( '.wc-block-mini-cart__drawer' ); if ( cgkit_cart_drawer ) { jQuery(document.body).trigger('added_to_cart'); if ( typeof cgkitLoadMiniCartBlocks == 'function' ) { cgkitLoadMiniCartBlocks(); } } } }); } var ckit_obp_clicked = false; var ckit_obp_clicked_id = 0; document.addEventListener('click', function(e){ $this = e.target; if( $this.classList.contains( 'ckobp-bullet' ) ) { e.preventDefault(); e.stopPropagation(); ckit_obp_clicked = true; ckit_obp_make_active($this, true); if( ckit_obp_clicked_id ){ clearTimeout( ckit_obp_clicked_id ); } ckit_obp_clicked_id = setTimeout(function(){ ckit_obp_clicked = false; ckit_obp_clicked_id = 0; }, 1000); } $thisp = $this.closest('.ckobp-prev'); if( $this.classList.contains( 'ckobp-prev' ) || $thisp ) { e.preventDefault(); e.stopPropagation(); var parent = $this.closest( '.commercekit-order-bump-wrap' ); var par_divs = parent.querySelector('.ckobp-bullets'); var $is_rtl = document.querySelector('body.rtl'); if( par_divs ){ var $index = parseInt(par_divs.getAttribute('data-index')); if( $index == 1 && ! $is_rtl ){ return true; } var $nindex = $is_rtl ? $index + 1 : $index - 1; var $bullet = parent.querySelector('.ckobp-bullets .ckobp-bullet[data-index="'+$nindex+'"]'); if( $bullet ){ $bullet.click(); } } } $thisp = $this.closest('.ckobp-next'); if( $this.classList.contains( 'ckobp-next' ) || $thisp ) { e.preventDefault(); e.stopPropagation(); var parent = $this.closest( '.commercekit-order-bump-wrap' ); var par_divs = parent.querySelector('.ckobp-bullets'); var $is_rtl = document.querySelector('body.rtl'); if( par_divs ){ var total = parseInt(par_divs.getAttribute('data-total')); var $index = parseInt(par_divs.getAttribute('data-index')); if( $index == total && ! $is_rtl ){ return true; } var $nindex = $is_rtl ? $index - 1 : $index + 1; var $bullet = parent.querySelector('.ckobp-bullets .ckobp-bullet[data-index="'+$nindex+'"]'); if( $bullet ){ $bullet.click(); } } } }); function ckit_obp_make_active($this, $scroll){ var parent = $this.closest( '.commercekit-order-bump-wrap' ); var $id = $this.getAttribute( 'id' ).replace( 'bullet-', '' ); var $mthis = parent.querySelector( '#' + $id ); var main_divs = parent.querySelectorAll('.commercekit-order-bumps .commercekit-order-bump'); $this.classList.add( 'active' ); $mthis.classList.add( 'active' ); main_divs.forEach(function(main_div){ if( main_div !== $mthis ){ main_div.classList.remove( 'active' ); } }); var sub_divs = parent.querySelectorAll('.ckobp-bullets .ckobp-bullet'); sub_divs.forEach(function(sub_divs){ if( sub_divs !== $this ){ sub_divs.classList.remove( 'active' ); } }); var $index = parseInt($mthis.getAttribute('data-index')); var par_divs = parent.querySelector('.ckobp-bullets'); if( par_divs ){ var total = parseInt(par_divs.getAttribute('data-total')); par_divs.setAttribute('data-index', $index); ckit_obp_update_prev_next(parent, total, $index); } if( $scroll ){ var $width = $mthis.clientWidth; var $scroll_left = ( $index - 1 ) * $width; var $is_rtl = document.querySelector('body.rtl'); if( $is_rtl ){ $scroll_left = -$scroll_left; } var ckit_obps = parent.querySelector('.commercekit-order-bumps'); if( ckit_obps ){ ckit_obps.scroll({ left: $scroll_left, top: 0, behavior: 'smooth' }); } } } document.addEventListener('scroll', function(e){ var $this = e.target; if( $this.classList && $this.classList.contains('commercekit-order-bumps') && !ckit_obp_clicked ){ var sub_div = $this.querySelector('.commercekit-order-bump:first-child'); if( sub_div ){ var parent = $this.closest( '.commercekit-order-bump-wrap' ); var $width = sub_div.clientWidth; var $scroll_left = Math.abs($this.scrollLeft); var $index = Math.round( $scroll_left / $width ) + 1; var $bullet = parent.querySelector('.ckobp-bullets .ckobp-bullet[data-index="'+$index+'"]'); if( $bullet ){ ckit_obp_make_active($bullet, false); } } } }, true); function ckit_obp_update_prev_next(parent, total, $index){ var prev = parent.querySelector('.ckobp-prev'); var next = parent.querySelector('.ckobp-next'); if( prev && next ){ next.classList.remove('ckobp-disabled'); prev.classList.remove('ckobp-disabled'); var $is_rtl = document.querySelector('body.rtl'); if( $is_rtl ){ if( $index == 1 ) { next.classList.add('ckobp-disabled'); } if( $index == total ) { prev.classList.add('ckobp-disabled'); } } else { if( $index == 1 ) { prev.classList.add('ckobp-disabled'); } if( $index == total ) { next.classList.add('ckobp-disabled'); } } } } document.addEventListener('keypress', function(e) { var active_elm = document.activeElement; if( active_elm && e.key == 'Enter' && ( active_elm.classList.contains('ckobp-prev') || active_elm.classList.contains('ckobp-next') ) ) { active_elm.click(); } }); var cgkit_updating_obp_views = false; function cgkit_update_order_bump_views() { var product_ids = []; var cgkit_obps = document.querySelectorAll( 'div.commercekit-order-bump[data-product-id]' ); if ( cgkit_obps.length > 0 ) { cgkit_obps.forEach( function( cgkit_obp ) { product_ids.push( cgkit_obp.getAttribute( 'data-product-id' ) ); } ); } if ( product_ids.length == 0 ) { return; } if ( cgkit_updating_obp_views ) { return; } var viewed = decodeURIComponent( document.cookie.match( /commercekit_obp_view_ids=([^;]+)/ ) ); viewed = viewed.replace( 'commercekit_obp_view_ids=', '' ); var viewedIds = viewed ? viewed.split(',') : []; var newIds = product_ids.filter( function( id ) { return viewedIds.indexOf( id ) === -1; } ); if ( newIds.length === 0 ) { return; } var ajax_nonce = ''; var nonce_input = document.querySelector( '#commercekit_nonce' ); if ( nonce_input ) { ajax_nonce = nonce_input.value; } var formData = new FormData(); formData.append( 'product_ids', product_ids ); formData.append( 'commercekit_nonce', ajax_nonce ); cgkit_updating_obp_views = true; fetch( commercekit_ajs.ajax_url + '=commercekit_orderbump_views', { method: 'POST', body: formData, } ).then( response => response.json() ).then( json => { cgkit_updating_obp_views = false; } ); } document.addEventListener( 'DOMContentLoaded', function() { if ( jQuery ) { jQuery( document ).on( 'wc_fragments_loaded wc_fragments_refreshed', function() { cgkit_update_order_bump_views(); } ); } } ); function cgkit_obp_toggle_selecter( obj ) { var wrap = obj.closest( '.commercekit-order-bump' ); if ( wrap ) { var obp_sel = wrap.querySelector('.cgkit-order-bump-selector'); if ( obp_sel ) { obp_sel.classList.toggle( 'active' ); } } } document.addEventListener( 'DOMContentLoaded', function() { document.addEventListener( 'click', function( event ) { if( ! event.target.classList.contains( 'cgkit-order-bump-clear' ) ) { return; } event.preventDefault(); event.stopPropagation(); var wrap = event.target.closest( '.cgkit-order-bump-selector' ); var wrap2 = event.target.closest( '.commercekit-order-bump' ); if( ! wrap || ! wrap2 ) { return; } var selects = wrap.querySelectorAll( '.cgkit-order-bump-attribute' ); selects.forEach( sel => { sel.value = ''; } ); if ( selects.length > 0 ) { var event_object = new Event( 'change', { bubbles: true } ); selects[0].dispatchEvent( event_object ); } wrap.setAttribute( 'data-gimg_id', '' ); cgkit_update_obp_selecter_image( wrap2 ); } ); document.addEventListener( 'change', function( event ) { if( ! event.target.classList.contains( 'cgkit-order-bump-attribute' ) ) { return; } var wrap = event.target.closest( '.cgkit-order-bump-selector' ); var wrap2 = event.target.closest( '.commercekit-order-bump' ); if( ! wrap || ! wrap2 ) { return; } var variations = wrap.dataset.variations ? JSON.parse( wrap.dataset.variations ) : []; var status_box = wrap.querySelector('.cgkit-order-bump-status'); var atc_btn = wrap2.querySelector('.cgkit-order-bump-atc'); var price_div = wrap2.querySelector('.ckobp-price'); if( ! status_box || ! atc_btn || ! price_div ) { return; } var original_price = price_div.getAttribute('data-price'); if( ! original_price ){ original_price = price_div.innerHTML; price_div.setAttribute('data-price', price_div.innerHTML); } var $select = event.target; var selected_option = $select.selectedOptions[0]; var gimg_id = selected_option.getAttribute( 'data-gimg_id' ); var selected = {}; var attr_count = 0; var select_count = 0; wrap.querySelectorAll( '.cgkit-order-bump-attribute' ).forEach( sel => { attr_count++; var attr_name = sel.dataset.attributeName; var value = sel.value; if ( value ) { select_count++; if ( attr_name.indexOf( 'attribute_' ) !== 0 ){ attr_name = 'attribute_' + attr_name; } selected[attr_name] = value; } } ); if ( attr_count != select_count ) { price_div.innerHTML = original_price; atc_btn.textContent = atc_btn.dataset.selectText; atc_btn.setAttribute( 'onclick', 'cgkit_obp_toggle_selecter(this);' ); status_box.textContent = ''; wrap.setAttribute( 'data-gimg_id', '' ); cgkit_update_obp_selecter_image( wrap2 ); return; } var matching = variations.find( v => { var ok = true; for ( var key in v.attributes ) { if ( ! selected[key] || selected[key] !== v.attributes[key] ) { ok = false; break; } } return ok; } ); if ( ! matching ) { price_div.innerHTML = original_price; atc_btn.textContent = atc_btn.dataset.selectText; atc_btn.setAttribute( 'onclick', 'cgkit_obp_toggle_selecter(this);' ); status_box.textContent = atc_btn.dataset.naText; wrap.setAttribute( 'data-gimg_id', '' ); cgkit_update_obp_selecter_image( wrap2 ); return; } if ( ! matching.is_in_stock ) { price_div.innerHTML = matching.price_html; atc_btn.textContent = atc_btn.dataset.selectText; atc_btn.setAttribute( 'onclick', 'cgkit_obp_toggle_selecter(this);' ); status_box.textContent = atc_btn.dataset.oosText; wrap.setAttribute( 'data-gimg_id', matching.cgkit_image_id ); cgkit_update_obp_selecter_image( wrap2 ); return; } if ( ! matching.is_purchasable ) { price_div.innerHTML = matching.price_html; atc_btn.textContent = atc_btn.dataset.selectText; atc_btn.setAttribute( 'onclick', 'cgkit_obp_toggle_selecter(this);' ); status_box.textContent = atc_btn.dataset.naText; wrap.setAttribute( 'data-gimg_id', matching.cgkit_image_id ); cgkit_update_obp_selecter_image( wrap2 ); return; } atc_btn.textContent = atc_btn.dataset.atcText; atc_btn.setAttribute( 'onclick', "commercekitOrderBumpAdd(" + matching.variation_id + ", this, '" + atc_btn.dataset.position + "');" ); status_box.textContent = ''; price_div.innerHTML = matching.price_html; wrap.setAttribute( 'data-gimg_id', matching.cgkit_image_id ); cgkit_update_obp_selecter_image( wrap2 ); } ); } ); function cgkit_update_obp_selecter_image( wrap ) { var attr_count = 0; var empty_count = 0; var select_count = 0; var gimg_id = ''; wrap.querySelectorAll( '.cgkit-order-bump-attribute' ).forEach( sel => { attr_count++; if ( sel.value == '' ) { empty_count++; } else { select_count++; } var selected_option = sel.selectedOptions[0]; var sel_img_id = selected_option.getAttribute( 'data-gimg_id' ); if ( sel_img_id != '' ) { gimg_id = sel_img_id; } } ); var clr_btn = wrap.querySelector( '.cgkit-obp-status-wrap' ); if ( clr_btn ) { if ( attr_count == empty_count ) { clr_btn.style.display = 'none'; } else { clr_btn.style.display = ''; } } var wrap2 = wrap.querySelector( '.cgkit-order-bump-selector' ); if ( ! wrap2 ) { return; } var images = JSON.parse( wrap2.getAttribute( 'data-images' ) ); if ( ! images || Object.keys( images ).length == 0 ) { return; } var img_img = wrap.querySelector( '.ckobp-image img' ); if ( ! img_img ) { return; } var vimg_id = wrap2.getAttribute( 'data-gimg_id' ); if ( select_count == attr_count && vimg_id != '' ) { gimg_id = vimg_id; } if ( gimg_id != '' && images.hasOwnProperty( 'img_' + gimg_id ) ) { var img_key = 'img_' + gimg_id; var img_src = img_img.getAttribute( 'data-obp-src' ); if ( ! img_src ) { img_img.setAttribute( 'data-obp-src', img_img.getAttribute( 'src' ) ); img_img.setAttribute( 'data-obp-srcset', '' ); img_img.setAttribute( 'data-obp-sizes', '' ); var img_srcset = img_img.getAttribute( 'srcset' ); var img_sizes = img_img.getAttribute( 'sizes' ); if ( img_srcset ) { img_img.setAttribute( 'data-obp-srcset', img_srcset ); } if ( img_sizes ) { img_img.setAttribute( 'data-obp-sizes', img_sizes ); } } if ( images[img_key].srcset ) { img_img.setAttribute( 'srcset', images[img_key].srcset ); } else { img_img.setAttribute( 'srcset', '' ); } if ( images[img_key].sizes ) { img_img.setAttribute( 'sizes', images[img_key].sizes ); } else { img_img.setAttribute( 'sizes', '' ); } img_img.setAttribute( 'src', images[img_key].src ); } else { var img_src = img_img.getAttribute( 'data-obp-src' ); var img_srcset = img_img.getAttribute( 'data-obp-srcset' ); var img_sizes = img_img.getAttribute( 'data-obp-sizes' ); if ( img_src ) { if ( img_srcset ) { img_img.setAttribute( 'srcset', img_srcset ); } else { img_img.setAttribute( 'srcset', '' ); } if ( img_sizes ) { img_img.setAttribute( 'sizes', img_sizes ); } else { img_img.setAttribute( 'sizes', '' ); } img_img.setAttribute( 'src', img_src ); } } } </script> <script id="wp-importmap" type="importmap"> {"imports":{"@wordpress/interactivity":"https://fivemx.com/wp-includes/js/dist/script-modules/interactivity/index.min.js?ver=efaa5193bbad9c60ffd1","@wordpress/interactivity-router":"https://fivemx.com/wp-includes/js/dist/script-modules/interactivity-router/index.min.js?ver=71aa17bac91628a0f874","@wordpress/a11y":"https://fivemx.com/wp-includes/js/dist/script-modules/a11y/index.min.js?ver=1c371cb517a97cdbcb9f"}} </script> <script id="woocommerce/product-collection-js-module" src="https://fivemx.com/wp-content/plugins/woocommerce/assets/client/blocks/woocommerce/product-collection.js?ver=892c2bfe326c817cd409" type="module"></script> <link rel="modulepreload" href="https://fivemx.com/wp-includes/js/dist/script-modules/interactivity/index.min.js?ver=efaa5193bbad9c60ffd1" id="@wordpress/interactivity-js-modulepreload" data-wp-fetchpriority="low"> <script id="wp-script-module-data-@wordpress/interactivity" type="application/json"> {"state":{"woocommerce/store-notices":{"notices":[]},"core/router":{"url":"https://fivemx.com/de/how-to-create-a-custom-fivem-loading-screen/"}}} </script> <script id="wp-script-module-data-@wordpress/interactivity-router" type="application/json"> {"i18n":{"loading":"Die Seite wird geladen, bitte warten.","loaded":"Die Seite wurde geladen."}} </script> <script> ( () => { const lazyloadRunObserver = () => { const lazyloadBackgrounds = document.querySelectorAll( `.e-con.e-parent:not(.e-lazyloaded)` ); const lazyloadBackgroundObserver = new IntersectionObserver( ( entries ) => { entries.forEach( ( entry ) => { if ( entry.isIntersecting ) { let lazyloadBackground = entry.target; if( lazyloadBackground ) { lazyloadBackground.classList.add( 'e-lazyloaded' ); } lazyloadBackgroundObserver.unobserve( entry.target ); } }); }, { rootMargin: '200px 0px 200px 0px' } ); lazyloadBackgrounds.forEach( ( lazyloadBackground ) => { lazyloadBackgroundObserver.observe( lazyloadBackground ); } ); }; const events = [ 'DOMContentLoaded', 'elementor/lazyload/observe', ]; events.forEach( ( event ) => { document.addEventListener( event, lazyloadRunObserver ); } ); } )(); </script> <!--Start of Tawk.to Script (0.9.3)--> <script id="tawk-script" type="text/javascript"> var Tawk_API = Tawk_API || {}; var Tawk_LoadStart; (function(){ if (navigator.webdriver === true || /HeadlessChrome/i.test(navigator.userAgent)) return; var loaded = false; var events = ['pointerdown', 'keydown', 'touchstart']; var load = function(){ if (loaded) return; loaded = true; events.forEach(function(eventName){ window.removeEventListener(eventName, load); }); Tawk_LoadStart = new Date(); (function(){ var s1 = document.createElement( 'script' ),s0=document.getElementsByTagName( 'script' )[0]; s1.async = true; s1.src = 'https://embed.tawk.to/6a60f4f514d8401d499dde5f/1ju5bpnpl'; s1.charset = 'UTF-8'; s0.parentNode.insertBefore( s1, s0 ); })(); }; events.forEach(function(eventName){ window.addEventListener(eventName, load, { once: true, passive: true }); }); if ('requestIdleCallback' in window) { window.requestIdleCallback(load, { timeout: 5000 }); } else { window.setTimeout(load, 3500); } })(); </script> <!--End of Tawk.to Script (0.9.3)--> <script type='text/javascript'> (function () { var c = document.body.className; c = c.replace(/woocommerce-no-js/, 'woocommerce-js'); document.body.className = c; })(); </script> <div class="wp-interactivity-router-loading-bar" data-wp-interactive="core/router/private" data-wp-class--start-animation="state.navigation.hasStarted" data-wp-class--finish-animation="state.navigation.hasFinished" ></div><div class="fivemx-exit-popup" data-fivemx-exit-popup data-fivemx-offer-campaign="welcome-2026-07" data-dismiss-until="2026-11-17" hidden><div class="fivemx-exit-popup__backdrop" data-fivemx-exit-popup-backdrop></div><div class="fivemx-exit-popup__card" role="dialog" aria-labelledby="fivemx-exit-popup-title" tabindex="-1"><button class="fivemx-exit-popup__close" type="button" data-fivemx-exit-popup-close aria-label="Angebot schließen" data-no-translation-aria-label="">×</button><strong class="fivemx-exit-popup__title" id="fivemx-exit-popup-title" data-no-translation="" data-trp-gettext="">Spare 20 % mit WELCOME</strong><p class="fivemx-exit-popup__body" data-no-translation="" data-trp-gettext="">Gültig bis 17. November 2026.</p><p class="fivemx-exit-popup__code"><code data-fivemx-exit-popup-code>WELCOME</code><button class="fivemx-exit-popup__copy" type="button" data-fivemx-exit-popup-copy data-copied-label="Code kopiert" data-fivemx-offer-action="copy_coupon" data-fivemx-offer-surface="exit_popup" data-fivemx-offer-campaign="welcome-2026-07" data-no-translation="" data-trp-gettext="" data-no-translation-data-copied-label="">Code kopieren</button></p><p class="fivemx-exit-popup__link"><a href="https://fivemx.com/de/sales/" data-fivemx-offer-action="view_sales" data-fivemx-offer-surface="exit_popup" data-fivemx-offer-campaign="welcome-2026-07" data-no-translation="" data-trp-gettext="">Angebote ansehen</a></p></div></div> <script id="fivemx-exit-popup"> (function () { var popup = document.querySelector('[data-fivemx-exit-popup]'); if (!popup) { return; } // Exit intent is a pointer gesture. Touch has no equivalent, and a // popup on a small screen is an interstitial Google penalises. var isPointerDevice = window.matchMedia && window.matchMedia('(hover: hover) and (pointer: fine)').matches; if (!isPointerDevice || window.innerWidth < 1024) { return; } var cookieName = 'fivemx_exit_popup_dismissed_until'; var cookieExpires = 'Tue, 17 Nov 2026 23:00:00 GMT'; var sessionKey = 'fivemxExitPopupShown'; var storageKey = 'fivemxExitPopupDismissedUntil'; var dismissUntil = popup.getAttribute('data-dismiss-until') || ''; if (document.cookie.indexOf(cookieName + '=' + encodeURIComponent(dismissUntil)) !== -1) { return; } try { if (window.localStorage.getItem(storageKey) === dismissUntil) { return; } if (window.sessionStorage.getItem(sessionKey) === '1') { return; } } catch (error) {} var card = popup.querySelector('.fivemx-exit-popup__card'); var closeButton = popup.querySelector('[data-fivemx-exit-popup-close]'); var backdrop = popup.querySelector('[data-fivemx-exit-popup-backdrop]'); var copyButton = popup.querySelector('[data-fivemx-exit-popup-copy]'); var lastFocused = null; var isOpen = false; var readyAt = Date.now() + 5000; function focusable() { return Array.prototype.filter.call( card.querySelectorAll('a[href], button:not([disabled]), input, [tabindex]:not([tabindex="-1"])'), function (node) { return node.offsetParent !== null; } ); } function close() { if (!isOpen) { return; } isOpen = false; popup.hidden = true; card.removeAttribute('aria-modal'); document.documentElement.classList.remove('fivemx-exit-popup-open'); try { window.localStorage.setItem(storageKey, dismissUntil); } catch (error) {} document.cookie = cookieName + '=' + encodeURIComponent(dismissUntil) + '; expires=' + cookieExpires + '; path=/; SameSite=Lax'; if (lastFocused && typeof lastFocused.focus === 'function') { lastFocused.focus(); } } function open() { if (isOpen || Date.now() < readyAt) { return; } // The bar carries the same offer. Do not say it twice at once. var bar = document.querySelector('[data-fivemx-promo-bar]'); if (bar && !bar.hidden && bar.style.display !== 'none') { return; } isOpen = true; lastFocused = document.activeElement; popup.hidden = false; card.setAttribute('aria-modal', 'true'); document.documentElement.classList.add('fivemx-exit-popup-open'); card.focus(); try { window.sessionStorage.setItem(sessionKey, '1'); } catch (error) {} } document.addEventListener('mouseout', function (event) { if (event.clientY <= 0 && !event.relatedTarget) { open(); } }); document.addEventListener('keydown', function (event) { if (!isOpen) { return; } if (event.key === 'Escape') { close(); return; } if (event.key !== 'Tab') { return; } var nodes = focusable(); if (!nodes.length) { return; } var first = nodes[0]; var last = nodes[nodes.length - 1]; if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus(); } else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus(); } }); if (closeButton) { closeButton.addEventListener('click', close); } if (backdrop) { backdrop.addEventListener('click', close); } if (copyButton) { copyButton.addEventListener('click', function () { var code = popup.querySelector('[data-fivemx-exit-popup-code]'); if (!code || !navigator.clipboard) { return; } navigator.clipboard.writeText(code.textContent.trim()).then(function () { copyButton.textContent = copyButton.getAttribute('data-copied-label') || copyButton.textContent; }).catch(function () {}); }); } }()); </script> <script id="fivemx-elementor-frontend-config-fallback">window.elementorFrontendConfig=window.elementorFrontendConfig||{"environmentMode":{"edit":false,"wpPreview":false,"isScriptDebug":false},"i18n":{"shareOnFacebook":"Auf Facebook teilen","shareOnX":"Share on X","pinIt":"Anheften","download":"Download","downloadImage":"Bild downloaden","fullscreen":"Vollbild","zoom":"Zoom","share":"Teilen","playVideo":"Video abspielen","previous":"Zurück","next":"Weiter","close":"Schließen","a11yCarouselPrevSlideMessage":"Vorheriger Slide","a11yCarouselNextSlideMessage":"Nächster Slide","a11yCarouselFirstSlideMessage":"This is the first slide","a11yCarouselLastSlideMessage":"This is the last slide","a11yCarouselPaginationBulletMessage":"Go to slide"},"is_rtl":false,"breakpoints":{"xs":0,"sm":480,"md":768,"lg":1025,"xl":1440,"xxl":1600},"responsive":{"breakpoints":{"mobile":{"label":"Mobil Hochformat","value":767,"default_value":767,"direction":"max","is_enabled":true},"mobile_extra":{"label":"Mobil Querformat","value":880,"default_value":880,"direction":"max","is_enabled":false},"tablet":{"label":"Tablet Hochformat","value":1024,"default_value":1024,"direction":"max","is_enabled":true},"tablet_extra":{"label":"Tablet Querformat","value":1200,"default_value":1200,"direction":"max","is_enabled":false},"laptop":{"label":"Laptop","value":1366,"default_value":1366,"direction":"max","is_enabled":false},"widescreen":{"label":"Breitbild","value":2400,"default_value":2400,"direction":"min","is_enabled":false}},"hasCustomBreakpoints":false},"version":"4.2.1","is_static":false,"experimentalFeatures":{"e_font_icon_svg":true,"additional_custom_breakpoints":true,"container":true,"e_optimized_markup":true,"e_panel_promotions":true,"e_pro_free_trial_popup":true,"nested-elements":true,"e_atomic_elements":true,"atomic_widgets_should_enforce_capabilities":true,"editor_mcp":true,"e_bc_migrations":true,"e_classes":true,"global_classes_should_enforce_capabilities":true,"e_variables":true,"e_variables_manager":true,"e_opt_in_v4_page":true,"e_opt_in_v4":true,"e_components":true,"e_interactions":true,"e_widget_creation":true,"import-export-customization":true},"urls":{"assets":"https://fivemx.com/wp-content/plugins/elementor/assets/","ajaxurl":"https://fivemx.com/wp-admin/admin-ajax.php","uploadUrl":"https://fivemx.com/wp-content/uploads"},"nonces":{"floatingButtonsClickTracking":"b62784dc79","atomicFormsSendForm":"f316b68f81"},"swiperClass":"swiper","settings":{"page":[],"editorPreferences":[]},"kit":{"active_breakpoints":["viewport_mobile","viewport_tablet"],"global_image_lightbox":"yes","lightbox_enable_counter":"yes","lightbox_enable_fullscreen":"yes","lightbox_enable_zoom":"yes","lightbox_enable_share":"yes","lightbox_title_src":"title","lightbox_description_src":"description"},"post":{"id":184927,"title":"How%20To%20Create%20a%20Custom%20FiveM%20Loading%20Screen","excerpt":"","featuredImage":"https://cdn.fivemx.com/wp-content/uploads/2025/04/fivem-loading-screen.webp"}};</script> <style id="woocommerce-product-collection-style-inline-css"> @keyframes wc-skeleton-shimmer{to{transform:translateX(100%)}}.wp-block-woocommerce-product-collection{margin-bottom:30px}.wp-block-woocommerce-product-collection .wc-block-components-product-stock-indicator{text-align:center}.wp-block-woocommerce-product-collection h2.wp-block-heading{font-size:var(--wp--preset--font-size--small,14px);line-height:1.4}.wp-block-woocommerce-product-collection .wc-block-components-notices:not(:has(*))+.wc-block-product-template{margin-block-start:0}@media(max-width:600px)and (hover:none)and (pointer:coarse){.wp-block-woocommerce-product-collection:has(.is-product-collection-layout-carousel) :where(.wc-block-next-previous-buttons.wc-block-next-previous-buttons){display:none}}.wc-block-components-notice-banner .wc-block-components-button.wc-block-components-notice-banner__dismiss[hidden]{display:none} /*# sourceURL=https://fivemx.com/wp-content/plugins/woocommerce/assets/client/blocks/woocommerce/product-collection-style.css */ </style> <style id="wp-interactivity-router-animations-inline-css"> .wp-interactivity-router-loading-bar { position: fixed; top: 0; left: 0; margin: 0; padding: 0; width: 100vw; max-width: 100vw !important; height: 4px; background-color: #000; opacity: 0 } .wp-interactivity-router-loading-bar.start-animation { animation: wp-interactivity-router-loading-bar-start-animation 30s cubic-bezier(0.03, 0.5, 0, 1) forwards } .wp-interactivity-router-loading-bar.finish-animation { animation: wp-interactivity-router-loading-bar-finish-animation 300ms ease-in } @keyframes wp-interactivity-router-loading-bar-start-animation { 0% { transform: scaleX(0); transform-origin: 0 0; opacity: 1 } 100% { transform: scaleX(1); transform-origin: 0 0; opacity: 1 } } @keyframes wp-interactivity-router-loading-bar-finish-animation { 0% { opacity: 1 } 50% { opacity: 1 } 100% { opacity: 0 } } /*# sourceURL=wp-interactivity-router-animations-inline-css */ </style> <style id="core-block-supports-inline-css"> .wp-container-core-group-is-layout-3c957fdc{flex-direction:column;align-items:center;} /*# sourceURL=core-block-supports-inline-css */ </style> <script id="trp-dynamic-translator-js-extra"> var trp_data = {"trp_custom_ajax_url":"https://fivemx.com/wp-content/plugins/translatepress-multilingual/includes/trp-ajax.php","trp_wp_ajax_url":"https://fivemx.com/wp-admin/admin-ajax.php","trp_language_to_query":"de_DE","trp_original_language":"en_US","trp_current_language":"de_DE","trp_skip_selectors":["[data-no-translation]","[data-no-dynamic-translation]","[data-trp-translate-id-innertext]","script","style","head","trp-span","translate-press","#billing_country","#shipping_country","#billing_state","#shipping_state","#select2-billing_country-results","#select2-billing_state-results","#select2-shipping_country-results","#select2-shipping_state-results",".woocommerce-loop-product__title","[data-trp-translate-id]","[data-trpgettextoriginal]","[data-trp-post-slug]"],"trp_base_selectors":["data-trp-translate-id","data-trpgettextoriginal","data-trp-post-slug"],"trp_attributes_selectors":{"text":{"accessor":"outertext","attribute":false},"block":{"accessor":"innertext","attribute":false},"image_src":{"selector":"img[src]","accessor":"src","attribute":true},"submit":{"selector":"input[type='submit'],input[type='button'], input[type='reset']","accessor":"value","attribute":true},"placeholder":{"selector":"input[placeholder],textarea[placeholder]","accessor":"placeholder","attribute":true},"title":{"selector":"[title]","accessor":"title","attribute":true},"a_href":{"selector":"a[href]","accessor":"href","attribute":true},"button":{"accessor":"outertext","attribute":false},"option":{"accessor":"innertext","attribute":false},"aria_label":{"selector":"[aria-label]","accessor":"aria-label","attribute":true},"video_src":{"selector":"video[src]","accessor":"src","attribute":true},"video_poster":{"selector":"video[poster]","accessor":"poster","attribute":true},"video_source_src":{"selector":"video source[src]","accessor":"src","attribute":true},"audio_src":{"selector":"audio[src]","accessor":"src","attribute":true},"audio_source_src":{"selector":"audio source[src]","accessor":"src","attribute":true},"picture_image_src":{"selector":"picture image[src]","accessor":"src","attribute":true},"picture_source_srcset":{"selector":"picture source[srcset]","accessor":"srcset","attribute":true},"image_alt":{"selector":"img[alt]","accessor":"alt","attribute":true},"meta_desc":{"selector":"meta[name=\"description\"],meta[property=\"og:title\"],meta[property=\"og:description\"],meta[property=\"og:site_name\"],meta[property=\"og:image:alt\"],meta[name=\"twitter:title\"],meta[name=\"twitter:description\"],meta[name=\"twitter:image:alt\"],meta[name=\"DC.Title\"],meta[name=\"DC.Description\"],meta[property=\"article:section\"],meta[property=\"article:tag\"]","accessor":"content","attribute":true},"page_title":{"selector":"title","accessor":"innertext","attribute":false},"meta_desc_img":{"selector":"meta[property=\"og:image\"],meta[property=\"og:image:secure_url\"],meta[name=\"twitter:image\"]","accessor":"content","attribute":true}},"trp_attributes_accessors":["outertext","innertext","src","value","placeholder","title","href","aria-label","poster","srcset","alt","content"],"gettranslationsnonceregular":"aa26fb909f","showdynamiccontentbeforetranslation":"","skip_strings_from_dynamic_translation":[],"skip_strings_from_dynamic_translation_for_substrings":{"href":["amazon-adsystem","googleads","g.doubleclick"]},"duplicate_detections_allowed":"100","trp_translate_numerals_opt":"no","trp_no_auto_translation_selectors":["[data-no-auto-translation]"]}; //# sourceURL=trp-dynamic-translator-js-extra </script> <script id="trp-dynamic-translator-js-before"> (function () { 'use strict'; var userAgent = String((window.navigator && window.navigator.userAgent) || ''); var isCrawler = new RegExp("ahrefs|bingbot|bot|crawler|dataforseo|dotbot|facebookexternalhit|gptbot|meta-externalagent|oai-searchbot|semrush|slurp|spider|yandex", 'i').test(userAgent); window.__fivemxCrawlerRuntime = isCrawler; if (isCrawler && typeof window.trp_data === 'object') { window.trp_data.trp_language_to_query = ''; } }()); //# sourceURL=trp-dynamic-translator-js-before </script> <script id="trp-dynamic-translator-js" defer src="https://fivemx.com/wp-content/plugins/translatepress-multilingual/assets/js/trp-translate-dom-changes.js?ver=3.3.1"></script> <script id="cgkit-js-cookie-js" defer src="https://fivemx.com/wp-content/plugins/commercegurus-commercekit/assets/js/js.cookie.min.js?ver=3.0.5"></script> <script id="commercekit-wishlist-js" defer src="https://fivemx.com/wp-content/plugins/commercegurus-commercekit/assets/js/wishlist.js?ver=2.5.2"></script> <script id="commercekit-ajax-search-js" defer src="https://fivemx.com/wp-content/plugins/commercegurus-commercekit/assets/js/ajax-search.js?ver=2.5.2"></script> <script id="shoptimizer-main-js" src="https://fivemx.com/wp-content/themes/shoptimizer/assets/js/main.min.js?ver=2.9.5"></script> <script id="shoptimizer-main-js-after"> document.querySelectorAll('.woocommerce-image__wrapper').forEach(carousel => { const carouselInner = carousel.querySelector('.shoptimizer-plp-image-wrapper'); const dots = carousel.querySelectorAll('.shoptimizer-plp-carousel--dot'); const carouselContainer = carousel.querySelector('.shoptimizer-plp-carousel-container'); // Check if the carousel container exists if (carouselContainer) { function updateDots() { const scrollLeft = carouselContainer.scrollLeft; const viewportWidth = carouselContainer.clientWidth; const index = Math.round(scrollLeft / viewportWidth); dots.forEach((dot, i) => { dot.classList.toggle('active', i === index); }); } let isScrolling; carouselContainer.addEventListener('scroll', () => { clearTimeout(isScrolling); isScrolling = setTimeout(() => { updateDots(); }, 50); }); // Initialize the dots updateDots(); } else { console.warn('Carousel container not found:', carousel); } }); jQuery( document ).ready( function( $ ) { $( 'body' ).on( 'added_to_cart', function( event, fragments, cart_hash ) { if ( ! $( 'body' ).hasClass( 'elementor-editor-active' ) ) { $( 'body' ).addClass( 'drawer-open' ); $( '#shoptimizerCartDrawer').focus(); } } ); } ); document.addEventListener( 'DOMContentLoaded', function() { document.addEventListener( 'click', function( event ) { var is_inner = event.target.closest( '.shoptimizer-mini-cart-wrap' ); if ( ! event.target.classList.contains( 'shoptimizer-mini-cart-wrap' ) && ! is_inner ) { document.querySelector( 'body' ).classList.remove( 'drawer-open' ); } var is_inner2 = event.target.closest( '.shoptimizer-cart' ); if ( event.target.classList.contains( 'shoptimizer-cart' ) || is_inner2 ) { var is_header = event.target.closest( '.site-header-cart' ); var is_shortcode = event.target.closest( '.shoptimizer-cart-shortcode' ); if ( is_header || is_shortcode ) { event.preventDefault(); document.querySelector( 'body' ).classList.toggle( 'drawer-open' ); document.getElementById('shoptimizerCartDrawer').focus(); } } if ( event.target.classList.contains( 'close-drawer' ) ) { document.querySelector( 'body' ).classList.remove( 'drawer-open' ); } } ); } ); // Mini Cart Ajax state. document.addEventListener( 'DOMContentLoaded', function() { document.querySelector( '#ajax-loading' ).style.display = 'none'; } ); ; ( function( $ ) { 'use strict'; var events_to_monitor = [ 'wc-ajax=get_refreshed_fragments', 'wc-ajax=remove_from_cart', ]; function handle_mini_cart_ajax_events( settings, show_loading ) { if ( events_to_monitor.some( function( event ) { return settings.url.indexOf( event ) !== -1; })) { if ( show_loading ) { $( '#ajax-loading' ).css( 'display', 'block' ); } else { $( '#ajax-loading' ).css( 'display', 'none' ); } } } events_to_monitor.forEach( function( event ) { $( document ).ajaxSend( function( event, jqXHR, settings ) { handle_mini_cart_ajax_events( settings, true ); }); $( document ).ajaxComplete( function( event, jqXHR, settings ) { handle_mini_cart_ajax_events( settings, false ); }); }); // Close anon function. }( jQuery ) ); var observer = new IntersectionObserver(function(entries) { if(entries[0].intersectionRatio === 0) document.querySelector('.col-full-nav').classList.add('is_stuck'); else if(entries[0].intersectionRatio === 1) document.querySelector('.col-full-nav').classList.remove('is_stuck'); }, { threshold: [0,1] }); var s_observer_elm = document.querySelector('.s-observer'); if ( s_observer_elm ) { observer.observe(s_observer_elm); } //# sourceURL=shoptimizer-main-js-after </script> <script async data-wp-strategy="async" fetchpriority="low" id="comment-reply-js" src="https://fivemx.com/wp-includes/js/comment-reply.min.js?ver=7.0.2"></script> <script id="sourcebuster-js-js" defer src="https://fivemx.com/wp-content/plugins/woocommerce/assets/js/sourcebuster/sourcebuster.min.js?ver=11.0.0"></script> <script id="wc-order-attribution-js-extra"> var wc_order_attribution = {"params":{"lifetime":0.9856262833675564,"session":30,"base64":false,"ajaxurl":"https://fivemx.com/wp-admin/admin-ajax.php","prefix":"wc_order_attribution_","allowTracking":true},"fields":{"source_type":"current.typ","referrer":"current_add.rf","utm_campaign":"current.cmp","utm_source":"current.src","utm_medium":"current.mdm","utm_content":"current.cnt","utm_id":"current.id","utm_term":"current.trm","utm_source_platform":"current.plt","utm_creative_format":"current.fmt","utm_marketing_tactic":"current.tct","session_entry":"current_add.ep","session_start_time":"current_add.fd","session_pages":"session.pgs","session_count":"udata.vst","user_agent":"udata.uag"}}; //# sourceURL=wc-order-attribution-js-extra </script> <script id="wc-order-attribution-js" defer src="https://fivemx.com/wp-content/plugins/woocommerce/assets/js/frontend/order-attribution.min.js?ver=11.0.0"></script> <script id="yay-currency-callback-general-js-extra"> var yay_callback_data = {"admin_url":"https://fivemx.com/wp-admin/admin.php?page=wc-settings","ajaxurl":"https://fivemx.com/wp-admin/admin-ajax.php","nonce":"abe58d2adb","isShowOnMenu":"0","isPolylangCompatible":"0","isDisplayFlagInSwitcher":"1","yayCurrencyPluginURL":"https://fivemx.com/wp-content/plugins/yaycurrency-pro/","converted_currency":[{"ID":174768,"currency":"USD","currencyPosition":"left","currencyCodePosition":"not_display","thousandSeparator":",","decimalSeparator":".","numberDecimal":"2","roundingType":"disabled","roundingValue":"1","subtractAmount":"0","rate":"1","fee":{"type":"fixed","value":"0"},"status":"1","paymentMethods":["all"],"countries":["default"],"symbol":"$"},{"ID":174769,"currency":"EUR","currencyPosition":"left","currencyCodePosition":"not_display","thousandSeparator":",","decimalSeparator":".","numberDecimal":"2","roundingType":"disabled","roundingValue":"1","subtractAmount":"0","rate":"0.8678","fee":{"type":"fixed","value":"0"},"status":"1","paymentMethods":["all"],"countries":["default"],"symbol":"€"},{"ID":174770,"currency":"GBP","currencyPosition":"left","currencyCodePosition":"not_display","thousandSeparator":",","decimalSeparator":".","numberDecimal":"2","roundingType":"disabled","roundingValue":"1","subtractAmount":"0","rate":"0.7438","fee":{"type":"fixed","value":"0"},"status":"1","paymentMethods":["all"],"countries":["default"],"symbol":"£"}],"checkout_diff_currency":"1","fallback_currency_code":"USD","default_currency_code":"USD","currency_symbol_position":"left","formatted_price_woo_blocks":"yes","fixed_product_price_enable":"0","show_approximate_price":"yes","cart_page":"","cookie_lifetime_days":"30","hide_dropdown_switcher":"","cookie_name":"yay_currency_widget","cookie_switcher_name":"yay_currency_do_change_switcher","cache_compatible":"1","current_theme":"shoptimizer","flag_fallbacks":{"default":"https://fivemx.com/wp-content/plugins/yaycurrency-pro/assets/flags/default.svg"},"apply_currency_before_cache":{"ID":174768,"rateFee":1},"minicart_contents_class":"a.cart-contents"}; //# sourceURL=yay-currency-callback-general-js-extra </script> <script id="yay-currency-callback-general-js" src="https://fivemx.com/wp-content/plugins/yaycurrency-pro/src/helpers/general.helper.min.js?ver=3.3.4"></script> <script id="yay-currency-callback-general-js-after"> (function () { function patchYayCurrencyHelper() { if (!window.YayCurrency_Callback || !window.YayCurrency_Callback.Helper) { return false; } var helper = window.YayCurrency_Callback.Helper; if (typeof helper.getRateFeeByCurrency === 'function' && !helper.getRateFeeByCurrency.__fivemxGuarded) { var getRateFeeByCurrency = helper.getRateFeeByCurrency; helper.getRateFeeByCurrency = function (currentCurrency) { try { return getRateFeeByCurrency.apply(this, arguments); } catch (error) { var fallbackCurrency = currentCurrency || (typeof helper.getCurrentCurrency === 'function' ? helper.getCurrentCurrency() : null); var fallbackRate = fallbackCurrency && Number.parseFloat(fallbackCurrency.rate); return Number.isFinite(fallbackRate) ? fallbackRate : 1; } }; helper.getRateFeeByCurrency.__fivemxGuarded = true; } if (typeof helper.handleFilterByPriceClassicEditor === 'function' && !helper.handleFilterByPriceClassicEditor.__fivemxGuarded) { var handleFilterByPriceClassicEditor = helper.handleFilterByPriceClassicEditor; helper.handleFilterByPriceClassicEditor = function (currencyID) { var applyCurrency = typeof helper.getCurrentCurrency === 'function' ? helper.getCurrentCurrency(currencyID) : null; if (!applyCurrency || !applyCurrency.currency || !applyCurrency.fee) { return; } return handleFilterByPriceClassicEditor.apply(this, arguments); }; helper.handleFilterByPriceClassicEditor.__fivemxGuarded = true; } return true; } if (!patchYayCurrencyHelper()) { document.addEventListener('DOMContentLoaded', patchYayCurrencyHelper, { once: true }); } }()); //# sourceURL=yay-currency-callback-general-js-after </script> <script id="yay-currency-callback-blocks-js-extra"> var yay_callback_data = {"admin_url":"https://fivemx.com/wp-admin/admin.php?page=wc-settings","ajaxurl":"https://fivemx.com/wp-admin/admin-ajax.php","nonce":"abe58d2adb","isShowOnMenu":"0","isPolylangCompatible":"0","isDisplayFlagInSwitcher":"1","yayCurrencyPluginURL":"https://fivemx.com/wp-content/plugins/yaycurrency-pro/","converted_currency":[{"ID":174768,"currency":"USD","currencyPosition":"left","currencyCodePosition":"not_display","thousandSeparator":",","decimalSeparator":".","numberDecimal":"2","roundingType":"disabled","roundingValue":"1","subtractAmount":"0","rate":"1","fee":{"type":"fixed","value":"0"},"status":"1","paymentMethods":["all"],"countries":["default"],"symbol":"$"},{"ID":174769,"currency":"EUR","currencyPosition":"left","currencyCodePosition":"not_display","thousandSeparator":",","decimalSeparator":".","numberDecimal":"2","roundingType":"disabled","roundingValue":"1","subtractAmount":"0","rate":"0.8678","fee":{"type":"fixed","value":"0"},"status":"1","paymentMethods":["all"],"countries":["default"],"symbol":"€"},{"ID":174770,"currency":"GBP","currencyPosition":"left","currencyCodePosition":"not_display","thousandSeparator":",","decimalSeparator":".","numberDecimal":"2","roundingType":"disabled","roundingValue":"1","subtractAmount":"0","rate":"0.7438","fee":{"type":"fixed","value":"0"},"status":"1","paymentMethods":["all"],"countries":["default"],"symbol":"£"}],"checkout_diff_currency":"1","fallback_currency_code":"USD","default_currency_code":"USD","currency_symbol_position":"left","formatted_price_woo_blocks":"yes","fixed_product_price_enable":"0","show_approximate_price":"yes","cart_page":"","cookie_lifetime_days":"30","hide_dropdown_switcher":"","cookie_name":"yay_currency_widget","cookie_switcher_name":"yay_currency_do_change_switcher","cache_compatible":"1","current_theme":"shoptimizer","flag_fallbacks":{"default":"https://fivemx.com/wp-content/plugins/yaycurrency-pro/assets/flags/default.svg"},"apply_currency_before_cache":{"ID":174768,"rateFee":1},"minicart_contents_class":"a.cart-contents"}; //# sourceURL=yay-currency-callback-blocks-js-extra </script> <script id="yay-currency-callback-blocks-js" defer src="https://fivemx.com/wp-content/plugins/yaycurrency-pro/src/helpers/blocks.helper.min.js?ver=3.3.4"></script> <script id="yay-currency-frontend-script-js-extra"> var yayCurrency = {"admin_url":"https://fivemx.com/wp-admin/admin.php?page=wc-settings","ajaxurl":"https://fivemx.com/wp-admin/admin-ajax.php","nonce":"abe58d2adb","isShowOnMenu":"0","isPolylangCompatible":"0","isDisplayFlagInSwitcher":"1","yayCurrencyPluginURL":"https://fivemx.com/wp-content/plugins/yaycurrency-pro/","converted_currency":[{"ID":174768,"currency":"USD","currencyPosition":"left","currencyCodePosition":"not_display","thousandSeparator":",","decimalSeparator":".","numberDecimal":"2","roundingType":"disabled","roundingValue":"1","subtractAmount":"0","rate":"1","fee":{"type":"fixed","value":"0"},"status":"1","paymentMethods":["all"],"countries":["default"],"symbol":"$"},{"ID":174769,"currency":"EUR","currencyPosition":"left","currencyCodePosition":"not_display","thousandSeparator":",","decimalSeparator":".","numberDecimal":"2","roundingType":"disabled","roundingValue":"1","subtractAmount":"0","rate":"0.8678","fee":{"type":"fixed","value":"0"},"status":"1","paymentMethods":["all"],"countries":["default"],"symbol":"€"},{"ID":174770,"currency":"GBP","currencyPosition":"left","currencyCodePosition":"not_display","thousandSeparator":",","decimalSeparator":".","numberDecimal":"2","roundingType":"disabled","roundingValue":"1","subtractAmount":"0","rate":"0.7438","fee":{"type":"fixed","value":"0"},"status":"1","paymentMethods":["all"],"countries":["default"],"symbol":"£"}],"checkout_diff_currency":"1","fallback_currency_code":"USD","default_currency_code":"USD","currency_symbol_position":"left","formatted_price_woo_blocks":"yes","fixed_product_price_enable":"0","show_approximate_price":"yes","cart_page":"","cookie_lifetime_days":"30","hide_dropdown_switcher":"","cookie_name":"yay_currency_widget","cookie_switcher_name":"yay_currency_do_change_switcher","cache_compatible":"1","current_theme":"shoptimizer","flag_fallbacks":{"default":"https://fivemx.com/wp-content/plugins/yaycurrency-pro/assets/flags/default.svg"},"apply_currency_before_cache":{"ID":174768,"rateFee":1}}; //# sourceURL=yay-currency-frontend-script-js-extra </script> <script id="yay-currency-frontend-script-js" defer src="https://fivemx.com/wp-content/plugins/yaycurrency-pro/src/script.min.js?ver=3.3.4"></script> <script id="yay-currency-third-party-js" defer src="https://fivemx.com/wp-content/plugins/yaycurrency-pro/src/compatibles/third-party.min.js?ver=3.3.4"></script> <script id="yay-currency-caching-script-js-extra"> var yay_currency_caching_data = {"ajax_url":"https://fivemx.com/wp-admin/admin-ajax.php","nonce":"b0007bbc44","rest_url":"https://fivemx.com/de/wp-json/yaycurrency/v1/caching","rest_nonce":"595b6dc136","should_refresh_fragment":"yes","yay_currency_current_url":"https://fivemx.com/de/how-to-create-a-custom-fivem-loading-screen"}; //# sourceURL=yay-currency-caching-script-js-extra </script> <script id="yay-currency-caching-script-js-before"> (function () { 'use strict'; var userAgent = String((window.navigator && window.navigator.userAgent) || ''); var isCrawler = new RegExp("ahrefs|bingbot|bot|crawler|dataforseo|dotbot|facebookexternalhit|gptbot|meta-externalagent|oai-searchbot|semrush|slurp|spider|yandex", 'i').test(userAgent); window.__fivemxCrawlerRuntime = isCrawler; if (isCrawler && typeof window.trp_data === 'object') { window.trp_data.trp_language_to_query = ''; } }()); (function ($, refreshUrl) { 'use strict'; if ( window.__fivemxCrawlerRuntime === true || !$ || typeof $.ajax !== 'function' || typeof window.yay_currency_caching_data !== 'object' || !refreshUrl ) { return; } var data = window.yay_currency_caching_data; var restUrl = String(data.rest_url || '').replace(/\/$/, ''); if (!restUrl || window.__fivemxYayCurrencyNonceGuard) { return; } window.__fivemxYayCurrencyNonceGuard = true; var originalAjax = $.ajax; var refreshRequest = null; var targetUrls = [ restUrl + '/get_price_html', restUrl + '/currency_switcher_html' ]; function restoreAjax() { if ($.ajax === guardedAjax) { $.ajax = originalAjax; } } function refreshNonce() { if (refreshRequest) { return refreshRequest; } refreshRequest = originalAjax.call($, { url: refreshUrl, method: 'GET', dataType: 'json', cache: false, headers: { 'X-Yay-Nonce-Request': '1', 'Cache-Control': 'no-cache' }, xhrFields: { withCredentials: true } }); return refreshRequest; } function guardedAjax(url, settings) { var options = typeof url === 'object' && url !== null ? url : settings; var targetUrl = options && typeof options.url === 'string' ? options.url : ''; var method = String((options && (options.type || options.method)) || 'GET').toUpperCase(); if (!options || method !== 'POST' || !targetUrls.includes(targetUrl) || options.__fivemxNonceReady) { return originalAjax.apply(this, arguments); } var context = this; var deferred = $.Deferred(); var activeRequest = null; var promise = deferred.promise(); refreshNonce() .done(function (response) { if (!response || !response.nonce) { deferred.rejectWith(this, arguments); restoreAjax(); return; } data.rest_nonce = response.nonce; var requestOptions = $.extend({}, options, { headers: $.extend({}, options.headers || {}, { 'X-WP-Nonce': response.nonce }), __fivemxNonceReady: true }); activeRequest = originalAjax.call(context, requestOptions); activeRequest .done(function () { deferred.resolveWith(this, arguments); }) .fail(function () { deferred.rejectWith(this, arguments); }); restoreAjax(); }) .fail(function () { deferred.rejectWith(this, arguments); restoreAjax(); }); promise.abort = function (statusText) { if (activeRequest && typeof activeRequest.abort === 'function') { activeRequest.abort(statusText); } else { deferred.rejectWith(context, [null, statusText || 'abort']); } return promise; }; return promise; } $.ajax = guardedAjax; }(window.jQuery, "https:\/\/fivemx.com\/wp-admin\/admin-ajax.php?action=fivemx_yaycurrency_rest_nonce")); //# sourceURL=yay-currency-caching-script-js-before </script> <script id="yay-currency-caching-script-js" src="https://fivemx.com/wp-content/plugins/yaycurrency-pro/src/compatibles/cache/yay-caching.min.js?ver=3.3.4"></script> <script id="enlighterjs-js" src="https://fivemx.com/wp-content/plugins/enlighter/cache/enlighterjs.min.js?ver=eQazT5C2%2FIg515i"></script> <script id="enlighterjs-js-after"> !function(e,n){if("undefined"!=typeof EnlighterJS){var o={"selectors":{"block":"pre.EnlighterJSRAW","inline":"code.EnlighterJSRAW"},"options":{"indent":4,"ampersandCleanup":true,"linehover":true,"rawcodeDbclick":false,"textOverflow":"break","linenumbers":true,"theme":"atomic","language":"generic","retainCssClasses":false,"collapse":false,"toolbarOuter":"","toolbarTop":"{BTN_RAW}{BTN_COPY}{BTN_WINDOW}{BTN_WEBSITE}","toolbarBottom":""}};(e.EnlighterJSINIT=function(){EnlighterJS.init(o.selectors.block,o.selectors.inline,o.options)})()}else{(n&&(n.error||n.log)||function(){})("Error: EnlighterJS resources not loaded yet!")}}(window,console); //# sourceURL=enlighterjs-js-after </script> <div class="fivemx-language-switcher" role="navigation" aria-label="Language" data-no-translation-aria-label=""><div class="trp-shortcode-switcher__wrapper" style="--bg:#ffffff;--bg-hover:#0000000d;--text:#143852;--text-hover:#1d2327;--border:1px solid #1438521a;--border-width:1px;--border-color:#1438521a;--border-radius:5px;--flag-radius:2px;--flag-size:18px;--aspect-ratio:4/3;--font-size:14px;--transition-duration:0.2s" role="group" data-open-mode="click"> <!-- ANCHOR (in-flow only; sizing/borders; inert) --> <div class="trp-language-switcher trp-ls-dropdown trp-shortcode-switcher trp-shortcode-anchor trp-open-on-click" aria-hidden="true" inert data-no-translation> <div class="trp-current-language-item__wrapper"> <a class="trp-language-item trp-language-item__default trp-language-item__current" data-no-translation href="https://fivemx.com/de/so-erstellen-sie-einen-benutzerdefinierten-fivem-ladebildschirm/" title="Deutsch"><img src="https://fivemx.com/wp-content/plugins/translatepress-multilingual/assets/flags/4x3/de_DE.svg" class="trp-flag-image" alt="German" role="presentation" loading="lazy" aria-hidden="true" /><span class="trp-language-item-name">Deutsch</span></a> <svg class="trp-shortcode-arrow" width="20" height="20" viewbox="0 0 20 21" fill="none" aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg"> <path d="M5 8L10 13L15 8" stroke="var(--text)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> </div> </div> <!-- OVERLAY (positioned; interactive surface) --> <div class="trp-language-switcher trp-ls-dropdown trp-shortcode-switcher trp-shortcode-overlay trp-open-on-click" role="navigation" aria-label="Sprachauswahl der Website" data-no-translation > <div class="trp-current-language-item__wrapper"> <div class="trp-language-item trp-language-item__default trp-language-item__current" data-no-translation role="button" aria-expanded="false" tabindex="0" aria-label="Change language: Deutsch" aria-controls="trp-shortcode-dropdown-6a759a0b53ab5" data-no-translation-aria-label=""><img src="https://fivemx.com/wp-content/plugins/translatepress-multilingual/assets/flags/4x3/de_DE.svg" class="trp-flag-image" alt="German" role="presentation" loading="lazy" aria-hidden="true" /><span class="trp-language-item-name">Deutsch</span></div> <svg class="trp-shortcode-arrow" width="20" height="20" viewbox="0 0 20 21" fill="none" aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg"> <path d="M5 8L10 13L15 8" stroke="var(--text)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> </div> <div class="trp-switcher-dropdown-list" id="trp-shortcode-dropdown-6a759a0b53ab5" role="group" aria-label="Verfügbare Sprachen" hidden inert > <a class="trp-language-item" href="https://fivemx.com/how-to-create-a-custom-fivem-loading-screen/" title="Englisch"> <img src="https://fivemx.com/wp-content/plugins/translatepress-multilingual/assets/flags/4x3/en_US.svg" class="trp-flag-image" alt="Englisch" role="presentation" loading="lazy" aria-hidden="true" /> <span class="trp-language-item-name" data-no-translation>English</span> </a> <a class="trp-language-item" href="https://fivemx.com/fr/comment-creer-un-ecran-de-chargement-fivem-personnalise/" title="Deutsch"> <img src="https://fivemx.com/wp-content/plugins/translatepress-multilingual/assets/flags/4x3/fr_FR.svg" class="trp-flag-image" alt="Französisch" role="presentation" loading="lazy" aria-hidden="true" /> <span class="trp-language-item-name" data-no-translation>Français</span> </a> <a class="trp-language-item" href="https://fivemx.com/pt/como-criar-uma-tela-de-carregamento-fivem-personalizada/" title="Português do Brasil"> <img src="https://fivemx.com/wp-content/plugins/translatepress-multilingual/assets/flags/4x3/pt_BR.svg" class="trp-flag-image" alt="Portugiesisch" role="presentation" loading="lazy" aria-hidden="true" /> <span class="trp-language-item-name" data-no-translation>Português do Brasil</span> </a> <a class="trp-language-item" href="https://fivemx.com/es/como-crear-una-pantalla-de-carga-fivem-personalizada/" title="Spanisch"> <img src="https://fivemx.com/wp-content/plugins/translatepress-multilingual/assets/flags/4x3/es_ES.svg" class="trp-flag-image" alt="Spanisch" role="presentation" loading="lazy" aria-hidden="true" /> <span class="trp-language-item-name" data-no-translation>Español</span> </a> </div> </div> </div> </div><div style="position:absolute;margin:-1px;padding:0;height:1px;width:1px;overflow:hidden;clip-path:inset(50%);border:0;word-wrap:normal !important;"><p id="a11y-speak-intro-text" class="a11y-speak-intro-text" hidden data-no-translation="" data-trp-gettext="">Benachrichtigungen</p><div id="a11y-speak-assertive" class="a11y-speak-region" aria-live="assertive" aria-relevant="additions text" aria-atomic="true"></div><div id="a11y-speak-polite" class="a11y-speak-region" aria-live="polite" aria-relevant="additions text" aria-atomic="true"></div></div> <script id="fivemx-plausible-woocommerce-events"> (function(config) { if (!window.plausible || window.fivemxPlausibleWooLoaded) return; window.fivemxPlausibleWooLoaded = true; function track(eventName, props, revenue) { var name = config.analytics_events && config.analytics_events[eventName]; if (!name) return; var options = {}; if (props) options.props = props; if (revenue) { options.revenue = revenue; } try { window.plausible(name, options); } catch (error) { // Storefront behavior must not depend on analytics transport availability. } try { window.dispatchEvent(new CustomEvent('fivemx:analytics', { detail: { event: eventName, props: props || {} } })); } catch (error) { // Qualitative replay filtering is optional and must never block Plausible. } } // Storefront modules can request canonical events only after this consent-gated runtime exists. window.fivemxAnalytics = Object.freeze({ track: function(eventName, props) { track(eventName, props); } }); function rememberOnce(key) { try { if (sessionStorage.getItem(key)) return false; sessionStorage.setItem(key, '1'); } catch (error) { // Continue without storage-based deduping when the browser blocks it. } try { if (localStorage.getItem(key)) return false; localStorage.setItem(key, '1'); } catch (error) { return true; } return true; } function rememberSessionOnce(key) { try { if (sessionStorage.getItem(key)) return false; sessionStorage.setItem(key, '1'); } catch (error) { return rememberRecently(key, 3000); } return true; } var recentEvents = {}; function rememberRecently(key, ttl) { var now = Date.now(); if (recentEvents[key] && now - recentEvents[key] < ttl) return false; recentEvents[key] = now; return true; } function cleanProperty(value, fallback) { value = String(value || fallback || '').trim().replace(/\s+/g, ' '); return value.slice(0, 120); } function canonicalPath(value) { value = cleanProperty(value, '/'); if (value.charAt(0) !== '/') value = '/' + value; if (value.length > 1 && value.indexOf('?') === -1 && value.charAt(value.length - 1) !== '/') value += '/'; return value; } function rememberJourneyContext(value) { value = cleanProperty(value, ''); if (!value) return; try { sessionStorage.setItem('fivemx_buyer_context', value); } catch (error) { // Tracking still works without session context persistence. } document.cookie = 'fivemx_buyer_context=' + encodeURIComponent(value) + '; Path=/; Max-Age=604800; SameSite=Lax' + (location.protocol === 'https:' ? '; Secure' : ''); } function journeyContext() { var context = cleanProperty(config.buyer_context || '', ''); if (context) return context; try { return cleanProperty(sessionStorage.getItem('fivemx_buyer_context') || '', ''); } catch (error) { return ''; } } // Attribution used to have exactly one input: a click on a link that // carried both `data-fivemx-shop-bridge` and an explicit // `data-fivemx-recommendation-context`. The modules that rendered // those links on the homepage, product pages, category archives and // the cart are switched off since the theme change, so on the // high-traffic paths there is nothing left to click. // // A campaign-decorated landing is an input that does not depend on // any module rendering a link: whoever arrives on a first-party // decorated URL is attributable, including in a new tab or from a // shared link, where no click handler on this page ever ran. // // It has to be read here rather than in PHP: Cloudflare APO strips // `utm_*` from the cache key, so the origin is not guaranteed to see // them, while the browser always does. function campaignContext() { var params; try { params = new URLSearchParams(location.search); } catch (error) { return ''; } if (params.get('utm_source') !== 'fivemx') return ''; return cleanProperty(params.get('utm_content') || params.get('utm_campaign') || '', ''); } var landingContext = campaignContext(); if (landingContext) rememberJourneyContext(landingContext); function homeServerTilesVariant() { var now = Date.now(); if ( !config.home_server_tiles_experiment_start_ms || !config.home_server_tiles_experiment_end_ms || now < Number(config.home_server_tiles_experiment_start_ms) || now >= Number(config.home_server_tiles_experiment_end_ms) ) return ''; if (window.fivemxHomeServerTilesVariant === 'control' || window.fivemxHomeServerTilesVariant === 'premium') { return window.fivemxHomeServerTilesVariant; } var match = document.cookie.match(/(?:^|; )fivemx_home_server_tiles_variant=([^;]*)/); var variant = match ? decodeURIComponent(match[1]) : ''; return variant === 'control' || variant === 'premium' ? variant : ''; } function qbcoreMidTicketVariant() { var now = Date.now(); if ( !config.qbcore_mid_ticket_experiment_start_ms || !config.qbcore_mid_ticket_experiment_end_ms || now < Number(config.qbcore_mid_ticket_experiment_start_ms) || now >= Number(config.qbcore_mid_ticket_experiment_end_ms) ) return ''; if (window.fivemxQbcoreMidTicketVariant === 'control' || window.fivemxQbcoreMidTicketVariant === 'treatment') { return window.fivemxQbcoreMidTicketVariant; } var match = document.cookie.match(/(?:^|; )fivemx_qbcore_mid_ticket_variant=([^;]*)/); var variant = match ? decodeURIComponent(match[1]) : ''; return variant === 'control' || variant === 'treatment' ? variant : ''; } function experimentProps(props) { var variant = qbcoreMidTicketVariant(); if (variant) { props.experiment_id = cleanProperty(config.qbcore_mid_ticket_experiment, ''); props.experiment_variant = variant; } return props; } function productProps(product) { product = product || {}; var props = { product_id: String(product.product_id || ''), product_name: String(product.product_name || '') }; if (product.category) props.category = String(product.category); if (typeof product.price !== 'undefined') props.price = Number(product.price || 0); if (product.currency) props.currency = String(product.currency); if (product.product_segment) props.product_segment = cleanProperty(product.product_segment, ''); if (product.framework) props.framework = cleanProperty(product.framework, ''); if (product.price_band) props.price_band = cleanProperty(product.price_band, ''); if (window.fivemxServerOfferVariant) { props.experiment_variant = cleanProperty(window.fivemxServerOfferVariant, ''); } var homeVariant = homeServerTilesVariant(); if (homeVariant) props.home_experiment_variant = homeVariant; experimentProps(props); var context = journeyContext(); if (context) props.buyer_context = context; props.source_surface = context || cleanProperty(config.page_surface || '', 'unknown'); return props; } document.addEventListener('click', function(event) { var link = event.target && event.target.closest ? event.target.closest('[data-fivemx-shop-bridge]') : null; if (!link) return; // A bridge link without an explicit recommendation context used // to record nothing at all. Several surfaces render exactly that // shape, so fall back to the page's own buyer context before // giving up. var recommendationContext = config.page_surface === 'server-pack-buying-guide' ? config.page_surface : (link.getAttribute('data-fivemx-recommendation-context') || link.getAttribute('data-fivemx-buyer-context') || cleanProperty(config.buyer_context || '', '')); if (recommendationContext) { rememberJourneyContext(recommendationContext); } if (config.page_surface === 'server-pack-buying-guide' && !link.hasAttribute('data-fivemx-product-click')) { var routeTarget = link.getAttribute('href') || '/fivem-servers/'; var routePath = '/fivem-servers/'; try { routePath = canonicalPath(new URL(routeTarget, location.origin).pathname); } catch (error) { routePath = '/fivem-servers/'; } var routeFramework = routePath.indexOf('qbcore-server-packs') !== -1 ? 'qbcore' : (routePath.indexOf('esx-server-packs') !== -1 ? 'esx' : 'all'); var routeKey = 'server_pack_route_' + routePath; if (rememberRecently(routeKey, 1500)) { track('promotion_select', { promotion_id: 'server-pack-route', action: routeFramework, product_segment: 'server_pack', framework: routeFramework, source_surface: 'server-pack-buying-guide', source_path: canonicalPath(location.pathname), target_path: routePath }); } } }, true); document.addEventListener('click', function(event) { var link = event.target && event.target.closest ? event.target.closest('[data-fivemx-content-link]') : null; if (!link) return; track('content_link_click', { source_content_id: cleanProperty(link.getAttribute('data-source-content-id'), ''), target_content_id: cleanProperty(link.getAttribute('data-target-content-id'), ''), cluster: cleanProperty(link.getAttribute('data-cluster'), ''), placement: cleanProperty(link.getAttribute('data-placement'), '') }); }, true); document.addEventListener('click', function(event) { var link = event.target && event.target.closest ? event.target.closest('[data-fivemx-presale-contact]') : null; if (!link) return; var productId = cleanProperty(link.getAttribute('data-fivemx-product-id'), ''); var sourcePath = canonicalPath(location.pathname); track('presale_contact', { product_id: productId, product_name: cleanProperty(link.getAttribute('data-fivemx-product-name'), ''), product_price: Number(link.getAttribute('data-fivemx-product-price') || 0), source_path: sourcePath }); }, true); document.addEventListener('click', function(event) { var link = event.target && event.target.closest ? event.target.closest('[data-fivemx-home-action]') : null; if (!link) return; var action = cleanProperty(link.getAttribute('data-fivemx-home-action'), 'unknown'); var target = link.getAttribute('data-fivemx-home-target') || link.getAttribute('href') || '/'; var targetPath = target; try { targetPath = new URL(target, location.origin).pathname; } catch (error) { targetPath = '/'; } var promotionProps = { promotion_id: 'homepage-marketplace', action: action, surface: 'homepage', target_path: canonicalPath(targetPath), source_path: canonicalPath(location.pathname) }; var homeVariant = homeServerTilesVariant(); if (homeVariant) promotionProps.home_experiment_variant = homeVariant; track('promotion_select', promotionProps); }, true); document.addEventListener('click', function(event) { var action = event.target && event.target.closest ? event.target.closest('[data-fivemx-offer-action]') : null; if (!action) return; track('promotion_select', { promotion_id: cleanProperty(action.getAttribute('data-fivemx-offer-campaign'), 'unknown'), action: cleanProperty(action.getAttribute('data-fivemx-offer-action'), 'unknown'), surface: cleanProperty(action.getAttribute('data-fivemx-offer-surface'), 'unknown'), source_path: canonicalPath(location.pathname) }); }, true); document.addEventListener('click', function(event) { var link = event.target && event.target.closest ? event.target.closest('[data-fivemx-product-click]') : null; if (!link) return; var productId = link.getAttribute('data-fivemx-product-id') || ''; var productName = link.getAttribute('data-fivemx-product-name') || link.textContent || ''; var productPrice = link.getAttribute('data-fivemx-product-price') || ''; var role = link.getAttribute('data-fivemx-product-role') || ''; var recommendationContext = config.page_surface === 'server-pack-buying-guide' ? config.page_surface : (link.getAttribute('data-fivemx-recommendation-context') || link.getAttribute('data-fivemx-buyer-context') || config.buyer_context || ''); var target = link.getAttribute('data-fivemx-bridge-target') || link.getAttribute('href') || ''; var sourcePath = canonicalPath(location.pathname); var key = 'buyer_product_click_' + sourcePath + '_' + target + '_' + productId; if (!rememberRecently(key, 1500)) return; if (recommendationContext) rememberJourneyContext(recommendationContext); var props = { product_id: cleanProperty(productId, ''), product_name: cleanProperty(productName, 'unknown'), product_role: cleanProperty(role, ''), bridge_target: cleanProperty(target, ''), source_path: sourcePath, source_surface: cleanProperty(link.getAttribute('data-fivemx-source-surface') || config.page_surface || recommendationContext, 'unknown') }; if (productPrice !== '') props.price = Number(productPrice || 0); var productSegment = link.getAttribute('data-fivemx-product-segment') || ''; var framework = link.getAttribute('data-fivemx-framework') || ''; var priceBand = link.getAttribute('data-fivemx-price-band') || ''; if (productSegment) props.product_segment = cleanProperty(productSegment, ''); if (framework) props.framework = cleanProperty(framework, ''); if (priceBand) props.price_band = cleanProperty(priceBand, ''); if (recommendationContext) props.buyer_context = cleanProperty(recommendationContext, ''); var homeVariant = homeServerTilesVariant(); if (homeVariant) props.home_experiment_variant = homeVariant; experimentProps(props); track('select_product', props); }, true); if (config.is_buyer_page && config.buyer_context) { var buyerViewKey = 'buyer_page_view_' + location.pathname; if (rememberOnce(buyerViewKey)) { rememberJourneyContext(config.buyer_context); } } if (config.is_product && config.product && config.product.product_id) { var p = config.product; track('product_view', productProps(p)); } function checkoutBaseProps(extra) { var context = journeyContext(); var props = { item_count: Number(config.cart_count || 0), cart_total: Number(config.cart_total || 0), currency: cleanProperty(config.currency || 'USD', 'USD'), buyer_context: context, source_surface: context || cleanProperty(config.page_surface || '', 'checkout') }; var cartSegment = config.cart_segment || {}; ['product_segment', 'server_pack_count', 'server_pack_product_ids', 'framework', 'price_band'].forEach(function(key) { if (cartSegment[key]) props[key] = cleanProperty(cartSegment[key], ''); }); Object.keys(extra || {}).forEach(function(key) { props[key] = extra[key]; }); var homeVariant = homeServerTilesVariant(); if (homeVariant) props.home_experiment_variant = homeVariant; return experimentProps(props); } function selectedPaymentMethod() { var selected = document.querySelector('input[name="payment_method"]:checked'); var method = selected ? String(selected.value || '') : ''; method = method.toLowerCase().replace(/[^a-z0-9_-]/g, '').slice(0, 64); return method || 'unknown'; } function checkoutFieldGroup(target) { if (!target) return 'unknown'; var field = String(target.name || target.id || '').toLowerCase(); if (target.tagName === 'IFRAME') { var frameContext = String(target.title || target.getAttribute('aria-label') || '').toLowerCase(); if (/payment|card|stripe|secure/.test(frameContext) || target.closest('.payment_box, .payment_method_stripe_cc')) return 'payment'; } if (field.indexOf('email') !== -1) return 'email'; if (field.indexOf('first_name') !== -1 || field.indexOf('last_name') !== -1) return 'name'; if (field.indexOf('terms') !== -1) return 'terms'; if (field.indexOf('payment_method') !== -1 || field.indexOf('stripe') !== -1 || field.indexOf('card') !== -1) return 'payment'; if (field.indexOf('coupon') !== -1) return 'coupon'; if (/country|state|address|city|postcode|phone|company/.test(field)) return 'address'; return 'other'; } function checkoutErrorSummary(form) { var groups = {}; var fields = {}; if (form && form.querySelectorAll) { var invalid = form.querySelectorAll( '.woocommerce-invalid input, .woocommerce-invalid select, .woocommerce-invalid textarea, ' + 'input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"]' ); Array.prototype.forEach.call(invalid, function(field) { var identifier = cleanProperty(field.name || field.id || 'unknown', 'unknown'); fields[identifier] = true; groups[checkoutFieldGroup(field)] = true; }); var terms = form.querySelector('input[name="terms"]'); if (terms && !terms.checked) { fields.terms = true; groups.terms = true; } } var orderedGroups = ['email', 'name', 'address', 'terms', 'payment', 'coupon', 'other']; var firstGroup = 'payment_or_server'; for (var index = 0; index < orderedGroups.length; index += 1) { if (groups[orderedGroups[index]]) { firstGroup = orderedGroups[index]; break; } } var invalidFieldCount = Object.keys(fields).length; return { error_stage: invalidFieldCount > 0 ? 'validation' : 'payment_or_server', error_group: firstGroup, invalid_field_count: invalidFieldCount }; } if (config.is_checkout && !config.is_order_received && config.cart_count > 0) { var checkoutKey = 'fivemx_plausible_checkout_start_' + location.pathname + '_' + String(config.cart_count) + '_' + String(config.cart_total); if (rememberSessionOnce(checkoutKey)) { track('checkout_start', checkoutBaseProps()); } var checkoutForm = document.querySelector('form.checkout, form.woocommerce-checkout'); var checkoutFormStarted = false; var checkoutAttempt = 0; var checkoutAttemptResolved = 0; var checkoutOutcomeTimer = 0; document.addEventListener('focusin', function(event) { if (checkoutFormStarted || !event.isTrusted || !checkoutForm || !checkoutForm.contains(event.target)) return; if (!event.target.matches || !event.target.matches('input, select, textarea')) return; checkoutFormStarted = true; track('checkout_form_start', checkoutBaseProps({ first_field_group: checkoutFieldGroup(event.target) })); }, true); document.addEventListener('change', function(event) { if (!event.isTrusted || !event.target.matches || !event.target.matches('input[name="payment_method"]')) return; track('checkout_payment_method_selected', checkoutBaseProps({ payment_method: selectedPaymentMethod() })); }, true); function trackPlaceOrder() { if (!rememberRecently('fivemx_checkout_place_order', 1500)) return; checkoutAttempt += 1; track('checkout_place_order', checkoutBaseProps({ payment_method: selectedPaymentMethod(), attempt_index: checkoutAttempt })); window.clearTimeout(checkoutOutcomeTimer); checkoutOutcomeTimer = window.setTimeout(function() { if (checkoutAttemptResolved >= checkoutAttempt || document.visibilityState === 'hidden') return; if (checkoutForm && checkoutForm.classList.contains('processing')) return; checkoutAttemptResolved = checkoutAttempt; track('checkout_error', checkoutBaseProps({ error_stage: 'client_validation_or_blocked', error_group: checkoutFieldGroup(document.activeElement), invalid_field_count: 0, payment_method: selectedPaymentMethod(), attempt_index: checkoutAttempt })); }, 2500); } if (checkoutForm) { checkoutForm.addEventListener('submit', trackPlaceOrder, true); } if (window.jQuery) { window.jQuery(checkoutForm || 'form.checkout') .off('.fivemxCheckout') .on('checkout_place_order.fivemxCheckout', trackPlaceOrder); window.jQuery(document.body) .off('.fivemxCheckout') .on('checkout_error.fivemxCheckout', function() { window.setTimeout(function() { if (checkoutAttemptResolved >= Math.max(1, checkoutAttempt)) return; window.clearTimeout(checkoutOutcomeTimer); checkoutAttemptResolved = Math.max(1, checkoutAttempt); var summary = checkoutErrorSummary(checkoutForm); summary.payment_method = selectedPaymentMethod(); summary.attempt_index = Math.max(1, checkoutAttempt); track('checkout_error', checkoutBaseProps(summary)); }, 0); }) .on('checkout_place_order_success.fivemxCheckout', function() { window.clearTimeout(checkoutOutcomeTimer); checkoutAttemptResolved = Math.max(1, checkoutAttempt); track('checkout_submit_success', checkoutBaseProps({ payment_method: selectedPaymentMethod(), attempt_index: Math.max(1, checkoutAttempt) })); }); } } var lastCtaSource = ''; function trackProductCtaClick(source) { if (!config.is_product) return; var props = productProps(config.product || {}); if (!props.product_id && !props.product_name) return; lastCtaSource = cleanProperty(source, 'single_product_form'); props.currency = config.currency || 'USD'; props.source_path = canonicalPath(location.pathname); props.cta_source = lastCtaSource; var key = 'product_cta_' + (props.product_id || props.product_name || 'unknown') + '_' + props.source_path; if (!rememberRecently(key, 1500)) return; track('select_product', props); } document.addEventListener('click', function(event) { var target = event.target && event.target.closest ? event.target.closest('[data-fivemx-buy-now="1"], [data-fivemx-mobile-buy-button="1"], [data-fivemx-cylex-desktop-buy-button="1"], form.cart button.single_add_to_cart_button, form.cart input.single_add_to_cart_button') : null; if (!target) return; var source = 'single_product_form'; if (target.getAttribute('data-fivemx-buy-now') === '1') source = 'product_buy_now'; if (target.getAttribute('data-fivemx-mobile-buy-button') === '1') source = 'mobile_buy_bar'; if (target.getAttribute('data-fivemx-cylex-desktop-buy-button') === '1') source = 'cylex_desktop_sticky'; trackProductCtaClick(source); }, true); function trackAddToCart(product, source) { product = product || config.product || {}; var props = productProps(product); if (!props.product_id && !props.product_name) return; props.currency = product.currency || config.currency || 'USD'; props.source_path = canonicalPath(location.pathname); props.cta_source = cleanProperty(source, 'cart_form_submit'); var key = 'add_to_cart_' + (props.product_id || props.product_name || 'unknown') + '_' + props.source_path; if (!rememberRecently(key, 3000)) return; track('add_to_cart', props); } document.addEventListener('click', function(event) { var link = event.target && event.target.closest ? event.target.closest('[data-fivemx-direct-cart="1"]') : null; if (!link) return; var product = { product_id: link.getAttribute('data-fivemx-product-id') || '', product_name: link.getAttribute('data-fivemx-product-name') || '', price: Number(link.getAttribute('data-fivemx-product-price') || 0), currency: config.currency || 'USD' }; var recommendationContext = link.getAttribute('data-fivemx-recommendation-context') || ''; if (recommendationContext) rememberJourneyContext(recommendationContext); var directCartSource = link.getAttribute('data-fivemx-cart-source') || 'recommendation_direct_cart'; trackAddToCart(product, directCartSource); }, true); document.addEventListener('submit', function(event) { var form = event.target; if (!form || !form.matches || !form.matches('form.cart')) return; if (!lastCtaSource) trackProductCtaClick('cart_form_submit'); trackAddToCart(config.product, lastCtaSource || 'cart_form_submit'); }, true); if (window.jQuery) { window.jQuery(document.body).on('added_to_cart', function(event, fragments, cartHash, button) { var product = Object.assign({}, config.product || {}); var $button = window.jQuery(button || []); var id = $button.data('product_id'); if (id) product.product_id = String(id); trackAddToCart(product, 'ajax_add_to_cart'); }); } })({"is_product":false,"is_checkout":false,"is_order_received":false,"is_buyer_page":false,"buyer_context":"","page_surface":"","currency":"USD","cart_total":0,"cart_count":0,"cart_segment":[],"product":[],"analytics_events":{"experiment_exposure":"experiment_exposure","product_view":"product_view","search":"search","search_zero_results":"search_zero_results","select_product":"select_product","promotion_select":"promotion_select","add_to_cart":"add_to_cart","cart_confirmed":"cart_confirmed","checkout_start":"checkout_start","checkout_confirmed":"checkout_confirmed","checkout_form_start":"checkout_form_start","checkout_payment_method_selected":"checkout_payment_method_selected","checkout_place_order":"checkout_place_order","checkout_error":"checkout_error","checkout_submit_success":"checkout_submit_success","purchase":"purchase","download":"download","content_link_click":"content_link_click","presale_contact":"presale_contact"},"home_server_tiles_experiment_start_ms":1789250400000,"home_server_tiles_experiment_end_ms":1791669600000,"home_server_tiles_experiment":"homepage_server_tiles_2026_09","qbcore_mid_ticket_experiment_start_ms":1785694908000,"qbcore_mid_ticket_experiment_end_ms":1788114108000,"qbcore_mid_ticket_experiment":"qbcore_mid_ticket_merchandising_2026_08"}); </script> </body> </html> <!-- Performance optimized by Redis Object Cache. Learn more: https://wprediscache.com -->