Ein Kopierknopf für Highlight.js (Deutsch (German))

Ein Kopierknopf für Highlight.js

Comments

NOTE: Apart from English (and even then it's questionable, I'm Scottish). These are machine translated in languages I don't read. If they're terrible please contact me.
You can see how this translation was done in this article.

Saturday, 28 September 2024

//

5 minute read

Einleitung

In dieser Website benutze ich Hightlight.js, um Code-Snippets Client-Seite zu rendern. Ich mag dies, da es meinen Server-Seitencode sauber und einfach hält. Allerdings wollte ich jedem Code-Snippet eine Kopiertaste hinzufügen, damit Benutzer den Code leicht in ihre Zwischenablage kopieren können. Das ist eine einfache Aufgabe, aber ich dachte, ich würde es hier für jeden dokumentieren, der das Gleiche tun möchte.

Oh und das alles wartet auf mich das Hinzufügen der Newsletter-Funktionalität, um tatsächlich auf der Website zu zeigen. Sobald ich die Energie dazu habe, füge ich das hinzu.

Der Endpunkt ist, dass wir einen Kopierknopf wie diesen auf der Website haben: Knopf kopieren

HINWEIS: Alles Guthaben für diesen Artikel geht an Faraz Patankar Wer ist der Artikel, den ich benutzt habe, um diesen zu erschaffen? Ich wollte nur die Änderungen dokumentieren, die ich hier vorgenommen habe, um meine eigene Referenz zu erhalten und mit anderen zu teilen.

Die Optionen

Es gibt eine Reihe von Möglichkeiten, dies zu tun, zum Beispiel gibt es eine Schaltflächen-Modul kopieren für Higlight.js aber ich wollte mehr Kontrolle über den Knopf und das Styling. Also kam ich rüber Dieser Artikel für das Hinzufügen einer Kopiertaste.

Die Probleme

Während dieser Artikel ist ein großer Ansatz, es hatte ein paar Probleme, die verhindert, dass es perfekt für mich:

  1. Es verwendet eine Schriftart, die ich nicht auf meiner Website (aber dann manuell hat die SVG auch, nicht sicher, warum) verwenden.
  // Lucide copy icon
    copyButton.innerHTML = `<svg class="h-4 w-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-copy"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>`;

Während dies funktioniert, benutze ich bereits BoxIcons auf dieser Website, die eine Symbol dort schon kopieren.

  1. Es verwendet eine Toast-Bibliothek, die ich nicht auf dieser Website habe.
  // Notify user that the content has been copied
      toast.success("Copied to clipboard", {
        description: "The code block content has been copied to the clipboard.",
      });
  1. Es klopft den y-Überfluss auf dem Code-Block und setzt das Symbol an der Unterseite, die ich nicht wollte. Also ist meine oben rechts.

Meine Anpassungen

Die Hauptfunktion

Dieses Plugin hooks in die after:highlightElement Event und fügt dem Codeblock eine Schaltfläche hinzu.

Zuerst habe ich den Code von Faraz kopiert und dann die folgenden Änderungen vorgenommen:

  1. Anstatt es am Ende des Codeblocks anzubringen, bereite ich es zum Anfang vor.
  2. Anstelle des SVG habe ich die BoxIcons-Version benutzt, indem ich diese Klassen einfach in die eingefügte Schaltfläche & Einstellung der Textisierung hinzugefügt habe. text-xl.
  3. Ich entfernte die Toast-Benachrichtigung und ersetzte sie durch eine einfache showToast Funktion, die ich auf meiner Website habe (siehe später)
  4. Ich fügte hinzu: aria-label und title auf die Schaltfläche für die Zugänglichkeit (und um einen schönen Schwebeeffekt zu geben).
hljs.addPlugin({
    "after:highlightElement": ({ el, text }) => {
        const wrapper = el.parentElement;
        if (wrapper == null) {
            return;
        }

        /**
         * Make the parent relative so we can absolutely
         * position the copy button
         */
        wrapper.classList.add("relative");
        const copyButton = document.createElement("button");
        copyButton.classList.add(
            "absolute",
            "top-2",
            "right-1",
            "p-2",
            "text-gray-500",
            "hover:text-gray-700",
            "bx",
            "bx-copy",
            "text-xl",
            "cursor-pointer"
        );
        copyButton.setAttribute("aria-label", "Copy code to clipboard");
        copyButton.setAttribute("title", "Copy code to clipboard");

        copyButton.onclick = () => {
            navigator.clipboard.writeText(text);

            // Notify user that the content has been copied
            showToast("The code block content has been copied to the clipboard.", 3000, "success");

        };
        // Append the copy button to the wrapper
        wrapper.prepend(copyButton);
    },
});

showToast Funktion

Das beruht auf einem Rasiererteil, das ich meinem Projekt hinzugefügt habe. Dieser Teil nutzt die DaisyUI Toast-Komponente um dem Benutzer eine Nachricht anzuzeigen. Ich mag diesen Ansatz, wie es hält die Javascript sauber und einfach und ermöglicht es mir, die Toast-Nachricht in der gleichen Weise wie der Rest der Website zu stylen.

<div id="toast" class="toast toast-bottom fixed z-50 hidden overflow-y-hidden">
    <div id="toast-message" class="alert">
        <div>
            <span id="toast-text">Notification message</span>
        </div>
    </div>
    <p class="hidden right-1 bx-copy  cursor-pointer alert-success alert-warning alert-error alert-info"></p>
</div>

Sie werden feststellen, dass dies auch eine seltsame versteckte p Tag unten, dies ist nur für Tailwind, um diese Klassen zu parsen, wenn es baut die Website CSS.

Die Javascript-Funktion ist einfach, sie zeigt einfach die Toast-Nachricht für eine festgelegte Zeit an und versteckt sie dann erneut.

window.showToast = function(message, duration = 3000, type = 'success') {
    const toast = document.getElementById('toast');
    const toastText = document.getElementById('toast-text');
    const toastMessage = document.getElementById('toast-message');

    // Set message and type
    toastText.innerText = message;
    toastMessage.className = `alert alert-${type}`; // Change alert type (success, warning, error)

    // Show the toast
    toast.classList.remove('hidden');

    // Hide the toast after specified duration
    setTimeout(() => {
        toast.classList.add('hidden');
    }, duration);
}

Wir können dies dann mit Hilfe der showToast Funktion in der copyButton.onclick ..........................................................................................................................................

showToast("The code block content has been copied to the clipboard.", 3000, "success");

Ich habe diesen Teil direkt an der Spitze meiner _Layout.cshtml Datei, so dass es auf jeder Seite verfügbar ist.

<partial name="_Toast"  />``

Wenn wir jetzt Blog-Posts zeigen, haben die Code-Blocks: Knopf kopieren

Schlussfolgerung

Das ist es also, eine einfache Änderung von Faraz' Code, damit es für mich funktioniert. Ich hoffe, das hilft jemand anderem da draußen.

logo

©2024 Scott Galloway