Du må være registrert og logget inn for å kunne legge ut innlegg på freak.no
X
LOGG INN
... eller du kan registrere deg nå
Dette nettstedet er avhengig av annonseinntekter for å holde driften og videre utvikling igang. Vi liker ikke reklame heller, men alternativene er ikke mange. Vær snill å vurder å slå av annonseblokkering, eller å abonnere på en reklamefri utgave av nettstedet.
  4 6252
Jeg skriver et Grease-/Tampermonkey script, der jeg vil endre fonten på en nettside til en font fra Google Fonts.

Den "vanlige" måten å importere en Google font er jo å sette dette inn i HTML:

Kode

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Tangerine">
Men scriptet kjøres jo bare som JS i etterkant, jeg kan jo ikke legge inn en HTML-tag på en side jeg ikke styrer..?

Har søkt mye om dette ("load/import font with JavaScript"), men alle piler peker meg bare mot Web Font Loader fra Google og Typekit, som etter sigende skal la meg importere fonts med JavaScript. Men også her må man jo sette inn HTML!?

Kode

<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
<script>
  WebFont.load({
    google: {
      families: ['Droid Sans', 'Droid Serif']
    }
  });
</script>
Noen som vet hvordan jeg kan få til dette? Ser Tampermonkey har en @resource-greie, men har ikke fått det til å funke, og har ikke klart å finne et eneste eksempel som gjør noe lignende. Om ikke Tampermonkey har noen funksjoner for dette spesielt, går det an å gjøre i ren JavaScript? Dette scriptet kjøres jo etter at siden er ferdig lastet inn, så om jeg manuelt injiserer de nevnte HTML-taggene i dokumentet, så kjøres vel resten av scriptet mitt før fonten er ferdig lastet inn uansett..? Kan jeg omgå dette? Async await? Hjeeelp. Kan da vel ikke være sååå vanskelig!?

Tusen takk for at dere vil hjelpe en JS noob!

Jeg vil altså bare få lastet inn fonten sånn at jeg kan bruke den i scriptet med f.eks.

Kode

document.body.style.fontFamily = "denne fonten her";
Sist endret av JSnoob; 10. januar 2021 kl. 11:18. Grunn: Automatisk sammenslåing med etterfølgende innlegg.
Du kan fint redigere HTMLen på en nettside med et tampermonkey-script. Så du skal gå fint å legge til den html-tagen via JS-kode
Sist endret av etse; 10. januar 2021 kl. 11:33.
Limited edition
Moff's Avatar
Det er ingen utfordringer knyttet til å gjøre dette, bare skriv koden slik du ellers ville gjort. JavaScript som legges til etter at nettsiden er lastet vil fungere som normalt. Et problem du kan møte på er at CSS-kode som ligger i nettsiden fra før overstyrer det du forsøker å gjøre. For å løse dette må du se på såkalt specificity, som sier noe om hvilke CSS-regler som skal gjelde hvis mer enn én regel er angitt. Veldig ofte vil du vinne denne kampen hvis du bruker inline-CSS (style-attributt direkte på HTML-elementet) og i tillegg bruker !important. Her er et eksempel (dette kan selvsagt løses på mange forskjellige måter, dette er langt i fra den eneste):

Kode

// ==UserScript==
// @name         Test
// @namespace    https://example.com/
// @version      1.0
// @description  Få freak.no til å se helt jævlig ut!
// @author       Moff
// @match        https://*.freak.no/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    var head = document.head;

    var e = document.createElement("link");
    e.setAttribute("rel", "preconnect");
    e.setAttribute("href", "https://fonts.gstatic.com");
    head.appendChild(e);

    e = document.createElement("link");
    e.setAttribute("rel", "stylesheet");
    e.setAttribute("href", "https://fonts.googleapis.com/css2?family=Hachi+Maru+Pop&display=swap");
    head.appendChild(e);

    e = document.createElement("style");
    e.appendChild(document.createTextNode("body * { font-family: 'Hachi Maru Pop', cursive !important; }"));
    head.appendChild(e);
})();
De to første <link>-elementene er for Google Fonts, for å laste inn fonter. Koden for dette finner du på fonts.google.com. Den siste bolken er for å lage et <style>-element og skrive litt CSS-kode inni. Alle 3 elementer legges til i <head> via document.head. Resultat:

Tusen takk for utfyllende svar! Det funket!

Men kan jeg spørre hvrfor du legger koden i en funksjon, som du kaller med en gang? Har det noen hensikt i motsetning til å bare la koden (funksjonsinnmaten) ligge i det globale scopet?

Ser forresten at det er et lite delay der på fonten. All annen styling jeg har lagt til utføres umiddelbart, mens fonten er default et lite øyeblikk før den swapper over. Er det noen måte å unngå dette på? Caching? Skjønner det er krevende om nettsiden skal laste inn fonten hver eneste gang den laster en side.

Og hvilken effekt har strict mode i denne funksjonen?
Sist endret av JavaScriptNoob; 12. januar 2021 kl. 17:29. Grunn: Automatisk sammenslåing med etterfølgende innlegg.
Limited edition
Moff's Avatar
Det er ingen spesiell grunn til å strukturere skriptet på denne måten, eller bruke strict mode. Dette er simpelten en template fra TamperMonkey, som fylles ut når du oppretter et nytt skript. Jeg vet ikke hvordan TamperMonkey fungerer i praksis, men jeg kan se for meg at de gjør dette for å endre scope for koden din slik at du ikke "forurenser" global scope. Dette kan jo være både nyttig og mot sin hensikt, avhengig av hva du prøver å gjøre.

Det at fonten bruker tid på å endre seg er nok helt opp til hvor rask enheten din er. Jeg merker ingenting på min PC, og det skal heller ikke være sånn at enheten laster ned hele fonten hver gang du åpner siden med dette skriptet. Fonten blir automatisk cachet så fremt du ikke aktivt har slått av denne funksjonen på en eller annen måte. Du kan eksperimentere med ulike fremgangsmåter for å øke hastigheten på innlasting av font. Det kan for eksempel hende at du kan få bedre ytelse ved å endre CSS-reglene til å være enten mer eller mindre spesifikke.