Deje que el sitio web hable por sí mismo:¡extensiones de Chrome!

¡Hola! chicos, soy Clark. En esta publicación, quiero compartir cómo usar las extensiones de Chrome y algún método de JavaScript. ¡Deja que el sitio web hable por sí mismo!

En el proyecto a continuación, usaré Time For Kids como ejemplo, crearé extensiones de Chrome para capturar contenido en el artículo de Time For Kids. Cuando obtenga el contenido del artículo, usaré SpeechSynthesisUtterance y SpeechSynthesis para hablar texto, son métodos de JavaScript.

Crear un proyecto de extensiones de Chrome

Ok, antes que nada, necesitamos crear un proyecto para las extensiones de Chrome, por lo que, como el proyecto npm necesita paquete.json, debe crear un archivo manifest.json, si desea que su proyecto pueda ser una extensión de Chrome.

El contenido de manifest.json a continuación:

{
  "manifest_version": 2,
  "name": "Reciting articles of time for kinds",
  "description": "Reciting articles of time for kinds",
  "version": "1.0.0",
  "icons": {
    "16": "icon.png",
    "48": "icon.png",
    "128": "icon.png"
  },
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },
  "permissions": [
    "activeTab"
  ],
  "content_scripts": [
    {
      "matches": [
        "https://www.timeforkids.com/*"
      ],
      "js": [
        "execute.js"
      ]
    }
  ]
}

Debemos prestar atención a algunos puntos:

  1. icons :Debes poner un archivo del mismo nombre en la carpeta raíz, es tu icono de extensiones de Chrome

  2. browser_action :Tiene dos atributos, el primero es default_icon , default_icon significa lo mismo para icons arriba, el segundo es default_popup , default_popup El valor de es un archivo HTML, podemos usarlo para desencadenar un evento.

  3. content_scripts :Es un atributo muy interesante, tiene dos atributos, el primero es matches y el segundo es js , matches puede definir un dominio, si los usuarios visitan páginas web en este dominio, entonces las extensiones de Chrome cargarán automáticamente el código del archivo JavaScript especificado por js .

Hasta ahora ya sabemos a través del archivo manifest.json que necesitamos crear otros dos archivos, que son popup.html y execute.js.

ventana emergente.html

Nuestro HTML no necesita demasiado complejo, solo dos botones son suficientes, uno es iniciar, el otro es detener:

<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml" style="width:100px;">
  <head>
    <title>Reciting articles</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>

  <body id="body">
    <button id="recite">Start Recite</button>
    <button id="stopRecite">Stop Recite</button>
    <script src="./popup.js"></script>
  </body>
</html>

Si observa el código anterior, puede encontrar que cargué en secreto una llamada de archivo JavaScript en popup.html, el archivo JavaScript es popup.js:

const getSelectedTab = (tabs) => {
  const tabId = tabs[0].id;
  const sendMessage = messageObj => (
    chrome.tabs.sendMessage(tabId, messageObj)
  );

  document.getElementById('recite').addEventListener(
    'click', () => sendMessage({ action: 'RECITE' })
  );
  document.getElementById('stopRecite').addEventListener(
    'click', () => sendMessage({ action: 'STOP_RECITE' })
  );
};

chrome.tabs.query({ currentWindow: true, }, getSelectedTab);

Excepto que podemos agregar un detector de eventos de hacer clic en el botón de inicio y detener en popup.js, también podemos usar la API de Chrome para controlar páginas web, como las siguientes dos:

El primero es chrome.tabs.query, puede encontrar todas las pestañas actualmente abiertas en el navegador Chrome. El primer parámetro establece la pestaña que se está usando actualmente. El segundo parámetro es una función de devolución de llamada.

la función de devolución de llamada en el código anterior es getSelectedTab y getSelectedTab recibe un parámetro llamado tabs , tabs es de tipo matriz, en el tabs Tendrá todos los datos de la pestaña condicional del partido, ¿recordó mis condiciones? Configuré la pestaña actualmente activa, por lo que solo tendrá una pestaña en las pestañas, aún así el tabs todavía es un tipo de matriz, por lo que necesitamos obtener los datos de la pestaña actualmente por tabs[0] .

El segundo es chrome.tabs.sendMessage, si las páginas web actuales tienen chrome.runtime.onMessage.addListener, entonces podemos permitir que las extensiones de Chrome se comuniquen con las páginas web actuales mediante el envío de mensajes a través de chrome.tabs.sendMessage

Pero en este momento, quizás pienses:"Todas las páginas web tienen chrome.runtime.onMessage.addListener, ¿cómo es eso posible?"

¡Sí! ¡tienes razón! Eso es imposible, ¿entonces fallamos?

¡No! ¿Recordaste que tenemos atributos muy interesantes en manifest.json? Es content_scripts , ¿Es lo mismo que crees?

ejecutar.js

Entonces, aunque la página web de destino no tiene chrome.runtime.onMessage.addListener, aún podemos agregarlo en las páginas web de destino mediante execute.js de content_scripts :

const onMessage = (message) => {
  switch (message.action) {
    case 'RECITE':
      /* play */
      break;
    case 'STOP_RECITE':
      /* stop */
      break;
    default:
      break;
  }
}

chrome.runtime.onMessage.addListener(onMessage);

Debido a que nuestro popup.html tiene dos botones, necesito usar switch para configurar dos tipos de eventos para ejecutar, uno es comenzar a recitar, el otro es detener recitar, luego podemos escribir un código para el evento de inicio y parada.

Primer evento de inicio, tenemos que obtener el contenido del artículo, así que observo la etiqueta HTML en las páginas web de time for kids, puedo encontrar el contenido del artículo, está en el segundo div de clase es columns small-12 medium-offset-2 medium-8 end :

Entonces puedo escribir una función para obtener texto de contenido:

const getArticleContent = () => {
  let articleContent = '';
  const article = document.body.getElementsByClassName('columns small-12 medium-offset-2 medium-8 end')[1];
  const paragraphs = article.querySelectorAll('p:not([class])');
  paragraphs.forEach((paragraph) => { articleContent += `${paragraph.innerText} `; });
  return articleContent;
};

A continuación, debemos usar SpeechSynthesisUtterance y SpeechSynthesis para hablar el texto:

const recite = () => {
  const articleContent = getArticleContent();
  const utterThis = new SpeechSynthesisUtterance(articleContent);
  utterThis.lang = 'en-US';

  const synth = window.speechSynthesis;
  synth.speak(utterThis);
};

Pero debe prestar atención a que SpeechSynthesisUtterance tiene mucha entonación nacional, y espero que el tiempo para los tipos sea un artículo en inglés, así que configuré utterThis.lang a en-US , si quieres conocer otros terrenos, puedes visitar DEMO de mdn para probarlo.

Ahora hemos terminado una función para recitar, por lo que podemos agregar la función al case 'RECITE' de switch , y el otro case 'STOP_RECITE' podemos usar cancel de SpeechSynthesis deja de recitar directamente:

const onMessage = (message) => {
  switch (message.action) {
    case 'RECITE':
        recite();
      break;
    case 'STOP_RECITE':
        window.speechSynthesis.cancel();
      break;
    default:
      break;
  }
}

chrome.runtime.onMessage.addListener(onMessage);

Finalmente, tenemos que probar si la extensión de Chrome es correcta. Ejecute, abra su Chrome y vaya a las extensiones:

A continuación, haga clic en cargar la extensión desempaquetada, luego elija su carpeta de proyecto de extensión de Chrome.

Cuando termine todos los pasos anteriores, puede ir a cualquier artículo de Time For Kids y usar sus extensiones de Chrome ¡deje que las páginas web hablen por sí mismas!

Pondría todo el código anterior en mi GitHub, ¡bienvenidos chicos, clonenlo y prueben ustedes mismos!

¡Ustedes pueden enviar el mensaje a continuación si tienen alguna pregunta!

Por otro lado, esta publicación se publica simultáneamente en mi blog:Deje que el sitio web hable por sí mismo:¡extensiones de Chrome!