Voer scripts uit op elke pagina

Maak uw eerste extensie die een nieuw element op de pagina invoegt.

Overzicht

Met deze tutorial bouwt u een extensie die de verwachte leestijd toevoegt aan elke Chrome-extensie en Chrome Web Store-documentatiepagina.

Verlenging van de leestijd op de welkomstpagina van de extensie
Verlenging van de leestijd op de welkomstpagina van de extensie.

In deze handleiding leggen we de volgende concepten uit:

  • Het extensiemanifest.
  • Welke pictogram een ​​extensie gebruikt.
  • Hoe u code in pagina's injecteert met behulp van inhoudsscripts .
  • Hoe je matchpatronen gebruikt.
  • Machtigingen voor extensies.

Voordat je begint

Deze handleiding gaat ervan uit dat je basiservaring hebt met webontwikkeling. We raden je aan de Hello World- tutorial te bekijken voor een introductie tot de workflow voor extensieontwikkeling.

Bouw de extensie

Maak om te beginnen een nieuwe map met de naam reading-time aan om de bestanden van de extensie te bewaren. Je kunt desgewenst de volledige broncode downloaden van GitHub .

Stap 1: Voeg informatie over de extensie toe

Het manifest-JSON-bestand is het enige vereiste bestand. Het bevat belangrijke informatie over de extensie. Maak een manifest.json -bestand in de root van het project en voeg de volgende code toe:

{
  "manifest_version": 3,
  "name": "Reading time",
  "version": "1.0",
  "description": "Add the reading time to Chrome Extension documentation articles"
}

Deze sleutels bevatten basismetadata voor de extensie. Ze bepalen hoe de extensie wordt weergegeven op de extensiepagina en, na publicatie, in de Chrome Web Store. Voor meer informatie kunt u de sleutels "name" , "version" en "description" bekijken op de overzichtspagina van het manifest .

💡 Andere feiten over het extensiemanifest

  • Deze moet zich aan de basis van het project bevinden.
  • De enige vereiste sleutels zijn "manifest_version" , "name" en "version" .
  • Tijdens de ontwikkeling worden opmerkingen ( // ) ondersteund, maar deze moeten worden verwijderd voordat u uw code uploadt naar de Chrome Web Store.

Stap 2: De pictogrammen opgeven

Dus, waarom heb je pictogrammen nodig? Hoewel pictogrammen optioneel zijn tijdens de ontwikkeling, zijn ze vereist als je van plan bent je extensie te distribueren via de Chrome Web Store. Ze verschijnen ook op andere plekken, zoals de pagina Extensiebeheer.

Maak een map images aan en plaats de pictogrammen erin. Je kunt de pictogrammen downloaden op GitHub . Voeg vervolgens de gemarkeerde code toe aan je manifest om pictogrammen te declareren:

{
  "icons": {
    "16": "images/icon-16.png",
    "32": "images/icon-32.png",
    "48": "images/icon-48.png",
    "128": "images/icon-128.png"
  }
}

Wij raden aan om PNG-bestanden te gebruiken, maar andere bestandsformaten zijn ook toegestaan, met uitzondering van SVG-bestanden.

💡 Waar worden deze pictogrammen met verschillende formaten weergegeven?

Icoongrootte Gebruik van iconen
16x16 Favicon op de pagina's en in het contextmenu van de extensie.
32x32 Windows-computers hebben deze grootte vaak nodig.
48x48 Wordt weergegeven op de pagina Extensies.
128x128 Wordt weergegeven bij installatie en in de Chrome Web Store.

Stap 3: Declareer het inhoudsscript

Extensies kunnen scripts uitvoeren die de inhoud van een pagina lezen en wijzigen. Dit worden contentscripts genoemd. Ze leven in een geïsoleerde wereld , wat betekent dat ze wijzigingen in hun JavaScript-omgeving kunnen aanbrengen zonder dat er conflicten ontstaan ​​met de contentscripts van hun hostpagina of andere extensies.

Voeg de volgende code toe aan manifest.json om een ​​inhoudsscript met de naam content.js te registreren.

{
  "content_scripts": [
    {
      "js": ["scripts/content.js"],
      "matches": [
        "https://developer.chrome.com/docs/extensions/*",
        "https://developer.chrome.com/docs/webstore/*"
      ]
    }
  ]
}

Het veld "matches" kan een of meer matchpatronen bevatten. Deze stellen de browser in staat te identificeren op welke sites de contentscripts moeten worden geïnjecteerd. Matchpatronen bestaan ​​uit drie delen: <scheme>://<host><path> . Ze kunnen ' * ' tekens bevatten.

💡 Geeft deze extensie een toestemmingswaarschuwing weer?

Wanneer een gebruiker een extensie installeert, informeert de browser hem/haar over wat de extensie kan doen. Contentscripts vragen toestemming om te worden uitgevoerd op sites die voldoen aan de criteria voor het matchpatroon.

In dit voorbeeld ziet de gebruiker de volgende toestemmingswaarschuwing:

Waarschuwing over toestemming die de gebruiker te zien krijgt bij het installeren van de leestijdextensie
Waarschuwing voor leestijdtoestemming.

Voor meer informatie over extensiemachtigingen, zie Machtigingen declareren en gebruikers waarschuwen .

Stap 4: Bereken en plaats de leestijd

Contentscripts kunnen het standaard Document Object Model (DOM) gebruiken om de inhoud van een pagina te lezen en te wijzigen. De extensie controleert eerst of de pagina het <article> -element bevat. Vervolgens worden alle woorden in dit element geteld en wordt een alinea aangemaakt die de totale leestijd weergeeft.

Maak een bestand met de naam content.js in een map met de naam scripts en voeg de volgende code toe:

function renderReadingTime(article) {
  // If we weren't provided an article, we don't need to render anything.
  if (!article) {
    return;
  }

  const text = article.textContent;
  const wordMatchRegExp = /[^\s]+/g; // Regular expression
  const words = text.matchAll(wordMatchRegExp);
  // matchAll returns an iterator, convert to array to get word count
  const wordCount = [...words].length;
  const readingTime = Math.round(wordCount / 200);
  const badge = document.createElement("p");
  // Use the same styling as the publish information in an article's header
  badge.classList.add("color-secondary-text", "type--caption");
  badge.textContent = `⏱️ ${readingTime} min read`;

  // Support for API reference docs
  const heading = article.querySelector("h1");
  // Support for article docs with date
  const date = article.querySelector("time")?.parentNode;

  (date ?? heading).insertAdjacentElement("afterend", badge);
}

renderReadingTime(document.querySelector("article"));

💡 Interessante JavaScript gebruikt in deze code

  • Reguliere expressies tellen alleen de woorden binnen het <article> -element.
  • insertAdjacentElement() wordt gebruikt om het leestijdknooppunt na het element in te voegen.
  • De eigenschap classList wordt gebruikt om CSS-klassenamen toe te voegen aan het element class-kenmerk.
  • Optionele chaining die wordt gebruikt om toegang te krijgen tot een objecteigenschap die ongedefinieerd of null is.
  • Nullish coalescing retourneert de <heading> als de <date> null of ongedefinieerd is.

Stap 5: Luister naar veranderingen

Met de huidige code wordt de leestijd niet toegevoegd aan het nieuwe artikel als u via de linkernavigatie naar een ander artikel gaat. Dit komt doordat onze site is geïmplementeerd als een Single Page Application (SPA) die softnavigatie uitvoert met behulp van de History API .

Om dit te verhelpen, kunnen we een MutationObserver gebruiken die luistert naar wijzigingen en de leestijd aan nieuwe artikelen toevoegt.

Om dit te doen, voegt u het volgende toe onderaan content.js :

const observer = new MutationObserver((mutations) => {
  for (const mutation of mutations) {
    // If a new article was added.
    for (const node of mutation.addedNodes) {
      if (node instanceof Element && node.tagName === 'ARTICLE') {
        // Render the reading time for this particular article.
        renderReadingTime(node);
      }
    }
  }
});

// https://developer.chrome.com/ is a SPA (Single Page Application) so can
// update the address bar and render new content without reloading. Our content
// script won't be reinjected when this happens, so we need to watch for
// changes to the content.
observer.observe(document.querySelector('devsite-content'), {
  childList: true
});

Test of het werkt

Controleer of de bestandsstructuur van uw project er als volgt uitziet:

De inhoud van de map met leestijd: manifest.json, content.js in de map met scripts en de map met afbeeldingen.

Laad uw extensie lokaal

Als u een uitgepakte extensie in de ontwikkelaarsmodus wilt laden, volgt u de stappen in Basisbeginselen van ontwikkeling .

Open een extensie of Chrome Web Store-documentatie

Hieronder staan ​​een aantal pagina's die u kunt openen om te zien hoe lang het duurt om elk artikel te lezen.

Het zou er zo uit moeten zien:

Leestijd die loopt op de Welkomstpagina
Uitbreiding Welkomstpagina met de Leestijd-uitbreiding

🎯 Mogelijke verbeteringen

Probeer op basis van wat u vandaag hebt geleerd een van de volgende dingen te implementeren:

  • Voeg een ander matchpatroon toe in manifest.json ter ondersteuning van andere Chrome-ontwikkelaarspagina 's, zoals bijvoorbeeld Chrome DevTools of Workbox .
  • Voeg een nieuw inhoudsscript toe dat de leestijd voor uw favoriete blogs of documentatiesites berekent.

Blijf bouwen

Gefeliciteerd met het afronden van deze tutorial 🎉. Blijf je vaardigheden ontwikkelen door andere tutorials in deze serie te volgen:

Verlenging Wat je leert
Focusmodus Om code op de huidige pagina uit te voeren nadat u op de extensieactie hebt geklikt.
Tabbladenbeheerder Om een ​​pop-up te maken waarmee u browsertabbladen kunt beheren.

Blijf verkennen

We hopen dat je hebt genoten van het bouwen van deze Chrome-extensie en dat je enthousiast bent om je Chrome-ontwikkelingstraject voort te zetten. We raden het volgende leerpad aan:

  • De ontwikkelaarshandleiding bevat tientallen extra koppelingen naar documentatie die relevant is voor het maken van geavanceerde extensies.
  • Extensies hebben toegang tot krachtige API's die verder gaan dan wat er op het open web beschikbaar is. De documentatie van Chrome API's behandelt elke API.