Einzelne Instanz des Symbols ändern

Diesen alten Beitrag wieder hervorholen: Changing a single instance of an icon

Ich muss einzelne Icons auf der gesamten Website ändern. Ich möchte nicht replaceIcon() verwenden und alle Instanzen dieses Icons überschreiben. Ich sehe, dass dies in der Vergangenheit für bestimmte Bereiche der Website möglich war, oder zumindest liest es sich so, aber nicht für die gesamte Website.

Zum Beispiel möchte ich EIN Zahnrad-Icon in der Suche ändern, um besser widerzuspiegeln, was passiert, wenn der Benutzer darauf klickt. Ich möchte nicht alle Zahnrad-Icons ändern.

Danke!

1 „Gefällt mir“

Schau dir diesen PR an, vielleicht kannst du etwas Ähnliches nur mit CSS machen:

3 „Gefällt mir“

Das wirkt etwas provisorisch, wie funktioniert das, wenn man durch die Tabs wechselt/nur mit der Tastatur?

2 „Gefällt mir“

wenn man sich in der Wüste befindet und scheinbar kein Wasser vorhanden ist, können Hacks sehr nützlich sein!

2 „Gefällt mir“

Leider sind wir nicht in der Wüste… wir bezahlen dafür, eine Plattform zu nutzen, um eine öffentliche Website zu hosten.

2 „Gefällt mir“

Welches Symbol ist das genau (wo erscheint es)? Wenn es den Anschein hat, dass es für andere nützlich sein könnte, können wir einen Alias dafür erstellen, um es separat ersetzen zu können.

2 „Gefällt mir“

Hier ist ein Beispiel, bei dem das Zahnrad nicht die Aktion der Schaltfläche zum Öffnen der erweiterten Suchseite widerspiegelt:

1 „Gefällt mir“

Wir verwenden hier standardmäßig ein „Slider“-Symbol (und es ist das einzige Vorkommen dieses Symbols in Discourse standardmäßig) – daher wäre es sicher, in diesem Fall replaceIcon() zu verwenden

image

Da wir keine API zum Ersetzen einzelner Symbole haben, können wir dies heute am besten unterstützen, indem wir Anfragen zur Hinzufügung neuer Aliase auswerten, die ähnliche Anwendungsfälle gruppieren.

Wir verwenden zum Beispiel d-liked als Alias für heart, sodass replaceIcon() gegen d-liked verwendet werden kann, um es im Like-Kontext zu ändern, anstatt jedes Vorkommen des Herzsymbols in der gesamten App zu ersetzen.

Es wäre schön, jedes einzelne Vorkommen ersetzen zu können, das ist keine ungewöhnliche Situation bei Themes – hoffentlich haben wir eines Tages eine API dafür.

Großartig, es sieht so aus, als hätte das Discourse-Team unseres auf das Einstellungssymbol geändert, also habe ich es behoben! Danke :pray:

2 „Gefällt mir“

Okay, ich scheine es jetzt zu verstehen, was ist das Urteil darüber. Schade zu wissen, dass es bis zu einem API-Update nicht verfügbar ist, also werde ich vorerst die Methode verwenden, die ich angewendet habe.

{

Sie können auch iconHTML verwenden, anstatt das Symbol manuell hinzuzufügen.
Etwas in der Art sollte funktionieren:

import { apiInitializer } from "discourse/lib/api";
import { iconHTML } from "discourse/lib/icon-library";

export default apiInitializer((api) => {
  api.onPageChange(() => {
    const btnIcon = document.querySelector("#create-topic .d-icon");
    if (btnIcon) {
      btnIcon.outerHTML = iconHTML("plus");
    }
  });
});
1 „Gefällt mir“

Das könnte etwas instabil werden.

Ich glaube, dass api.onPageChange beim Routenwechsel ausgelöst wird.

Das ist gut vor dem Rendering.

Daher besteht das Risiko, dass die Elemente nicht gerendert sind, bevor du versuchst, sie zu finden und zu überschreiben.

Vielleicht hast du Glück, aber es ist nicht garantiert. Daher schlägt awesomerobot vor, dass es schön wäre, wenn es eine spezielle API gäbe …

(@Don, ich glaube, dein Lösungsansatz hat ein ähnliches Problem)

2 „Gefällt mir“

Ja, du hast Recht! Das ist nicht sehr stabil. Vielleicht kann es mit requestAnimationFrame oder MutationObserver stabiler gemacht werden? :thinking: aber ja, am besten wäre eine dedizierte API, wie du erwähnt hast.

2 „Gefällt mir“

Danke für den Hinweis – Sie haben absolut Recht. Die alleinige Verwendung von api.onPageChange kann unzuverlässig sein, da sie bei Routenänderungen und nicht nach dem DOM-Rendering ausgelöst wird. Das bedeutet, dass die Gefahr einer Race Condition besteht, bei der der Button #create-topic möglicherweise noch nicht existiert, wenn das Skript versucht, darauf zuzugreifen.

 api.onPageChange(() => {
        const targetSelector = "#create-topic";

        const tryEnhanceButton = () => {
            const button = document.querySelector(targetSelector);

            if (button) {
                // Beobachter trennen, nachdem das Element gefunden wurde
                observer.disconnect();

                // Den Button vorübergehend ausblenden, während wir das Icon ersetzen
                button.style.display = "none";

                // Altes Icon entfernen, falls vorhanden
                const oldIcon = button.querySelector("svg");
                if (oldIcon) oldIcon.remove();

                // Neues Font Awesome SVG-Icon erstellen und einfügen
                const newIcon = document.createElementNS("http://www.w3.org/2000/svg", "svg");
                newIcon.setAttribute("class", "fa d-icon d-icon-feather-pointed svg-icon svg-string");
                newIcon.setAttribute("xmlns", "http://www.w3.org/2000/svg");
                newIcon.innerHTML = '<use href="#feather-pointed"></use>';

                button.insertBefore(newIcon, button.firstChild);

                // Den Button wieder anzeigen
                button.style.display = "block";
            }
        };

        // Änderungen am DOM beobachten und versuchen, den Button zu verbessern, wenn er hinzugefügt wird
        const observer = new MutationObserver(() => tryEnhanceButton());
        observer.observe(document.body, { childList: true, subtree: true });

        // Sofort versuchen, da es möglicherweise bereits vorhanden ist
        tryEnhanceButton();
    });

@Don Ich habe MutationObserver eingebunden, um sicherzustellen, dass das Skript nur ausgeführt wird, wenn das Ziel-Element tatsächlich existiert. Es trennt sich selbst, nachdem es seine Aufgabe erfüllt hat, um unnötigen Overhead zu vermeiden. Es wird immer noch ein sofortiger Check versucht, falls das Element bereits vorhanden ist.

Ich kann das gewünschte SVG nicht aus dem Discourse-Icon-System abrufen, obwohl ich es als Admin-SVG-Icon-Subset registriert habe, da es anscheinend in Fontawesome, aber nicht in Discourse vorhanden ist.

1 „Gefällt mir“