Неперехваченная błąd typu: Nie można odczytać właściwości null (czytanie "addEventListener") Rozszerzenie Chrome

0

Pytanie

Robię rozszerzenie chrome do autouzupełniania. A mianowicie, po kliknięciu przycisku formularz wprowadzania danych na stronie sieci web zawartości zostanie wypełniona tekstem z popup.html. Otrzymuję ten błąd "nie można odczytać właściwości null", począwszy od tego miejsca, gdzie dodałem detektor zdarzeń do swojej przycisku. [Неперехваченная błąd typu: Nie można odczytać właściwości null (czytanie "addEventListener")][1]

Oto mój plik html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Autofill</title>
    <link rel="stylesheet" href="style.css">
    
  </head>
  <body>

    <p id="testText">Text to put</p>
  
    <button id="fillForm">Fill!</button>

    
    <script src="app.js" ></script>
  </body>
  
</html>

Oto mój app.js

console.log('background running!!!')
let testtext = document.getElementById('testText')

let button = document.getElementById('fillForm')
button.addEventListener('click', buttonClick);

function buttonClick(){
    params = {
        active: true,
        currentWindow: true
    }
    chrome.tabs.query(params, gotTabs);

    function gotTabs(tabs){
        let text = testtext.innerHTML
        let content = {
        username: text
        } 
        chrome.tabs.sendMessage(tabs[0].id, content);
    }
}

Oto mój content.js

console.log("Receiving message...")
chrome.runtime.onMessage.addListener(gotMessage);

function gotMessage(message, sender, sendReponse){
    document.getElementById('email').value = content.username
    
}

W końcu, mój manifest.json

{
    "name": "Resume Autofiller",
    "description": "Build an Extension!",
    "version": "1.0",
    "manifest_version": 2,
    "browser_action":{
        "default_popup": "index.html"
    },
    "permissions": [
        "activeTab",
        "<all_urls>"
    ],
    "content_scripts": [
        {
            "matches": ["<all_urls>"],
            "js": [ "content.js" ]
        } 
    ],
    "background": {
        "scripts": ["app.js"]
      }
    
  }

Czytałem w Internecie, że muszę umieścić swój znacznik skryptu w dolnej części znacznika body, ale nadal pojawia się ten błąd. Czuję, że obserwuję czymś oczywistym, więc każda pomoc będzie bardzo wdzięczna. Dziękuję!! W załączeniu błąd, którą dostaję. [1]: https://i.stack.imgur.com/GyNXO.png

1

Najlepsza odpowiedź

0

Jak już wspomniano, usuwanie tła z manifestu to naprawi, ale w przykładzie kodu, wydaje się, że istnieje koncepcyjne zamieszanie, dlatego chciałbym wyjaśnić, dlaczego to rozwiązanie działa.

Scenariusz nazywał app.js wygląda na to, że jest on przeznaczony do podręcznego scenariusza, ale jest używany jako tło scenariusza w przykładzie. Okno pop-up różni się od tła. To pomoże zrozumieć różnicę między tymi dwoma częściami rozbudowy i ich wielokrotnego użycia. Dla zapewnienia ciągłości następujące wyjaśnienie będzie odnosić się do wersji i warunków MV3.

Tło: "Pracownik usługi w tle uruchamia się, gdy jest to konieczne, i zwalniana, gdy jest bezczynny [...] Organizuj tła scenariusze wokół wydarzeń, od których zależy rozszerzenie. Definicja funkcjonalnie istotnych zdarzeń pozwala tle scenariuszy do bezczynności, aż te wydarzenia nie zostaną uruchomione, i zapobiega pomijanie ważnych wyzwalaczy rozszerzeniem" (Zarządzanie zdarzeniami z pomocą pracowników służby). Uwaga dodatkowa: tło dosłownie znajduje się w tle trybie; nie ma widocznego interfejsu użytkownika. Użytkownik nie będzie współpracować z przyciskami w tle (choć można wysyłać zdarzenia w tle w celu dalszego przetwarzania przez wysłanie wiadomości). Rozważmy tło jak jednoczęściowa.

Okno pop-up: jest To jedno z możliwych miejsc do świadczenia interfejsu użytkownika dany. Okno pop-up jest aktywowany przez użytkownika, щелкающим ikonę rozszerzenia i zniszczone, gdy okienko traci ostrość (również po zamknięciu karty), i ponownie uruchomiony ponownie, gdy użytkownik kliknie ikonę następnym razem. "Jak i tło scenariusz, ten plik musi być ogłoszony w manifeście, aby Chrome mógł przedstawić go w wyskakującym oknie rozszerzenia. Do tego należy dodać obiekt czynności w manifest i zainstaluj popup.html jak akcja default_popup." (Wyobraź sobie interfejs użytkownika). W wyskakującym oknie można dodać przyciski i inne elementy, na które użytkownik może kliknąć. Okno pop-up jest specyficzne dla każdej karty. Po otwarciu kilku okien przeglądarki i dwukrotnie ikonę, można jednocześnie otworzyć kilka okien pop-up.

Krótko mówiąc: błąd występuje z powodu wyszukiwania elementu przycisku w tle, gdy takich przycisków nie; usuwanie klucza manifestu zapobiegnie to.


Minimalny przepływ przykład

manifest.json: background klucz usunięto

{
  "name": "Resume Autofiller",
  "description": "Build an Extension!",
  "version": "1.0",
  "manifest_version": 2,
  "browser_action":{
    "default_popup": "index.html"
  },
  "permissions": [
    "activeTab",
    "<all_urls>"
  ],
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": [ "content.js" ]
    }
  ]
}

index.html: bez zmian

(style.css spowoduje błąd "nie znaleziono", ale nie powoduje niepokoju w tej sprawie)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Autofill</title>
    <link rel="stylesheet" href="style.css">
    
  </head>
  <body>

    <p id="testText">Text to put</p>
  
    <button id="fillForm">Fill!</button>

    
    <script src="app.js" ></script>
  </body>
  
</html>

app.js: zmieniany tekst dziennika, istotnych zmian nie ma

console.log('popup running!!!')
let testtext = document.getElementById('testText')

let button = document.getElementById('fillForm')
button.addEventListener('click', buttonClick);

function buttonClick(){
    params = {
        active: true,
        currentWindow: true
    }
    chrome.tabs.query(params, gotTabs);

    function gotTabs(tabs){
        let text = testtext.innerHTML
        let content = {
            username: text
        }
        chrome.tabs.sendMessage(tabs[0].id, content);
    }
}

content.js: trochę zmienił dane wyjściowe dziennika, wypowiadał się na spotkanie

chrome.runtime.onMessage.addListener(gotMessage);

function gotMessage(message, sender, sendResponse){
    console.log("Receiving message...")
    console.log('message', JSON.stringify(message));
    // next line has undefined references, commenting out
    // document.getElementById('email').value = content.username
}
2021-11-21 21:21:52

dziękuję, usunąłem tło scenariusz z manifestu, jednak nadal pojawia się ten sam błąd. Jedyna różnica w tym, że kontekst wyświetla bieżącą kartę, w której jestem, w przeciwieństwie do _generated_background_page.html to było pokazane wcześniej. Czytając w internecie, można naprawić "właściwość jest ustawiona na wartość null" przycisku, albo sprawdzając błędy nazewnictwa, albo dodając detektor zdarzeń DOMContentLoaded, że zrobiłem to i to, i nadal pojawia się ten sam błąd
Chris Wu

Dobrze, pozwól mi opublikować minimalny przepływ przykład. Ja uderzać redagować odpowiedź.
Neea

W tle nie ma przycisku, jeśli nie została ona generowany programowo pierwszej. getElementById będzie wracać niepewna, po sprawdzeniu nazewnictwa lub gotowości pobierania zawartości. Tło należy traktować jako bezgłowy (choć w mv2 można przeglądać wygenerowanego przez stronę, ale rzeczywisty użytkownik jej nie zobaczy).
Neea

wow, to pomogło wyjaśnić wiele rzeczy, sprawiłem, że to działa. Bardzo wdzięczny!!!! Było to związane z wysłaniem wiadomości (message.username zamiast content.username)
Chris Wu

W innych językach

Ta strona jest w innych językach

Русский
..................................................................................................................
Italiano
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................