Polyfills er ko­de­kom­po­nen­ter, der gør nyere web­funk­tio­ner brugbare i browsere, der ikke un­der­støt­ter sådanne funk­tio­ner som standard. Denne artikel forklarer, hvad disse praktiske ko­de­kom­po­nen­ter er, og hvordan du kan bruge dem.

Hvad er polyfills, og hvilke sprog kan de skrives i?

En polyfill, også kaldet en Po­ly­fil­ler, er en kodeblok af va­ri­e­ren­de kom­plek­si­tet, der gør moderne HTML-, CSS- eller Ja­va­Script-funk­tio­ner til­gæn­ge­li­ge i ældre browsere, der ikke un­der­støt­ter dem indbygget. De fleste polyfills er skrevet i Ja­va­Script, men andre webpro­gram­me­rings­sprog kan også danne grundlag for filler-scripts. Nogle af de vigtigste funk­tio­ner, som polyfills gør til­gæn­ge­li­ge på tværs af for­skel­li­ge web­brow­se­re, er HTML5-kom­po­nen­ter som bitmap-baserede canvas-elementer til grafik, di­a­gram­mer og ani­ma­tio­ner.

Note

Udtrykket “polyfill” stammer fra det populære britiske mærke Polyfilla, som er et fyldstof til renove­rings- og re­stau­re­rings­ar­bej­de. We­b­ud­vik­le­ren Remy Sharp så en passende sam­men­lig­ning mellem fyld­stof­fet og disse nyttige wor­ka­ro­und-koder, da formålet med begge er at udfylde huller. Med sidst­nævn­te er de huller, der skal udfyldes, huller i brow­ser­funk­tio­na­li­te­ten. Begrebet blev opfundet i Sharps bog In­tro­ducing HTML5 fra 2009, som han skrev sammen med Bruce Lawson. Polyfill etab­le­re­de sig ef­ter­føl­gen­de som den of­fi­ci­el­le be­teg­nel­se for sådanne ko­de­kom­po­nen­ter.

Hvilke typer polyfills findes der?

Det er ikke til­fæl­digt, at udtrykket polyfill er tæt forbundet med HTML5. Med sine avan­ce­re­de funk­tio­ner, der blandt andet har gjort flas­hvi­deo­er over­flø­di­ge, er den femte version af hypertext markup language blevet en fast del af in­ter­net­tet. Un­der­støt­tel­sen af HTML5 i browsere har dog udviklet sig ret langsomt. Ud over de polyfills, der er oprettet til HTML5-elementer, bruges polyfill-ko­de­blok­ke også til at integrere følgende we­b­e­le­men­ter:

  • SVG-grafik: SVG-formatet SVG (Scalable Vector Graphics), som W3C-konsor­ti­et begyndte at anbefale som stan­dard­for­mat for vek­tor­gra­fik i 2001, vandt først frem med HTML5. Men fordi mange browsere endnu ikke un­der­støt­ter dette format, findes der SVG-polyfills såsom svgweb.
  • EC­MA­Script: EC­MA­Script er den stan­dar­di­se­re­de kerne i Ja­va­Script og opdateres re­gel­mæs­sigt for at udvide sprogets funk­tio­na­li­tet. Funk­tio­ner som Promise-objekter eller Symbol-funk­tio­ner gøres til­gæn­ge­li­ge i ældre browsere gennem polyfills som Ja­va­Script-stan­dard­bi­bli­o­te­ket core-js.
  • Web­s­to­ra­ge: Cookie-al­ter­na­ti­ver som lokal storage (lang­tidslag­ring på kli­ent­si­den) og session storage (lagring begrænset til den aktuelle session), samlet kendt som web­s­to­ra­ge eller DOM Storage, un­der­støt­tes ikke af alle brow­ser­ver­sio­ner. Den MIT-li­cen­se­re­de web­s­to­ra­ge-polyfill er en velkendt løsning på dette problem.
  • Cross-Origin Resource Sharing (CORS): CORS giver we­bap­pli­ka­tio­ner adgang til we­bres­sour­cer, der er placeret uden for ens egen server. Mange ældre browsere un­der­støt­ter ikke denne da­ta­ud­veks­ling. Ja­va­Script-pakken XDomain og CORS-polyfill XHook kan hjælpe med at løse dette problem.
  • CSS (Cascading Style Sheets): I årevis har CSS været et af de vigtigste værktøjer til at designe det visuelle layout af hjem­mesi­der. Over tid er sty­les­he­ets blevet mere alsidige, hvilket har gjort polyfills populære til at kom­mu­ni­ke­re med ældre browsere. Et af de bedst kendte værktøjer er css-polyfills.js.
  • Ge­o­lo­ka­li­se­ring: I lang tid blev Ge­o­lo­ca­tion API (der bruges til at overføre en brugers placering) ikke un­der­støt­tet af browsere og kunne kun bruges med hjælp fra et ekstra browser-plugin. Med en polyfill kan du give denne funk­tio­na­li­tet til brugere med ældre brow­ser­ver­sio­ner, der ikke un­der­støt­ter API’en indbygget.

Hvordan bruges polyfills? (In­klu­de­rer ko­de­ek­semp­ler)

Du kan direkte indlejre polyfill Ja­va­Script-kode eller polyfill-scripts i HTML-do­ku­men­tet på et websted. Disse in­te­gre­res pro­blem­frit i den ek­si­ste­ren­de kildekode og udføres kun, hvis browseren ikke un­der­støt­ter den på­gæl­den­de web­funk­tion. Dette gøres typisk ved hjælp af Ja­va­Scripts if for at kon­trol­le­re for manglende un­der­støt­tel­se. Manglen på un­der­støt­tel­se kan derefter omdannes til en be­tin­gel­se for at aktivere scriptet. I de to følgende eksempler il­lu­stre­rer vi, hvordan man im­ple­men­te­rer dette, og viser dig, hvordan den generelle struktur af en polyfill ser ud.

Eksempel 1: Polyfill til Ja­va­Script-metoden startsWith()

if (!String.prototype.startsWith) {
    String.prototype.startsWith = function (searchString, position) {
        position = position || 0;
        return this.indexOf(searchString, position) === position;
    };
}
ja­va­script

Dette lille Ja­va­Script-uddrag gør det muligt for den kaldende browser at bruge startsWith(), selvom den ikke un­der­støt­ter den indbygget. Denne metode, der er en del af EC­MA­Script 6-spe­ci­fi­ka­tio­nen, kon­trol­le­rer, om en streng begynder med tegnet eller tegn­se­ri­en fra en anden streng. Hvis det er tilfældet, re­tur­ne­res ‘true’, ellers re­tur­ne­res ‘false’. Du kan finde en mere kompleks, optimeret version til in­te­gra­tion af startsWith()GitHub-siden til­hø­ren­de ud­vik­le­ren Mathias Bynens.

Note

Den her viste kode virker ikke, hvis webkli­en­ten blokerer Ja­va­Script eller har de­ak­ti­ve­ret scripts­pro­get i sine indstil­lin­ger.

Eksempel 2: Polyfill til we­bop­be­va­ring

Denne Ja­va­Script-polyfill er en enkel kod­nings­løs­ning, der gør lokal og ses­sions­lag­ring til­gæn­ge­lig i ældre brow­ser­model­ler.

if (typeof window.localStorage === 'undefined' || typeof window.sessionStorage === 'undefined') {
    (function () {
        var data = {};
        var Storage = function (type) {
            function setData() {
                // Implement the logic to set data into storage
                var storageData = JSON.stringify(data);
                document.cookie = type + '=' + storageData + ';path=/';
            }
            function clearData() {
                data = {};
                setData();
            }
            return {
                length: 0,
                clear: function () {
                    clearData();
                    this.length = 0;
                },
                getItem: function (key) {
                    return data[key] === undefined ? null : data[key];
                },
                key: function (i) {
                    var ctr = 0;
                    for (var k in data) {
                        if (ctr == i) return k;
                        ctr++;
                    }
                    return null;
                },
                removeItem: function (key) {
                    delete data[key];
                    this.length--;
                    setData();
                },
                setItem: function (key, value) {
                    data[key] = value + '';
                    this.length++;
                    setData();
                }
            };
        };
        // Set the local and session storage properties inside the window object
        if (typeof window.localStorage === 'undefined') window.localStorage = new Storage('local');
        if (typeof window.sessionStorage === 'undefined') window.sessionStorage = new Storage('session');
    })();
}
ja­va­script

Oven­stå­en­de kode er en IIFE ( Im­me­di­a­te­ly Invoked Function Expres­sion). Inden browseren indlæser den, kon­trol­le­rer en komm if i første kodelinje imid­ler­tid, om klienten un­der­støt­ter web­tek­no­lo­gi­er­ne. Hvis det er tilfældet, re­tur­ne­rer if en falsk værdi, fordi typerne for lokal og ses­sions­lag­ring allerede er defineret. Dette re­sul­te­rer i, at po­ly­fil­let kasseres.

Gå til ho­ved­me­nu­en