Добавление кнопки "Отключить" в расширение Chrome

Я хочу добавить кнопку отключения в всплывающем окне моего расширения chrome, которое будет иметь функцию паузы, например, расширение Adblock. Это будет оставаться приостановленным во всех вкладках, пока кнопка не будет нажата, чтобы снова включить ее. У меня есть следующий код на месте, однако кнопка и функциональность в настоящее время не работают.

Файл Popup.js:

function disableButton() {
    var disableButton = document.getElementById("disableButton");
    var isExtensionOn = true;
    if (disableButton.innerHTML == "Disable") {
        isExtensionOn = false;
    } else if (disableButton.innerHTML == "Enable") {
        isExtensionOn = true;
    } else {
        alert("Error");
    }
}

document.addEventListener('DOMContentLoaded', function () {
    var singleButton = document.getElementById("singleButton");
    var br1 = document.getElementById("br1");
    var br2 = document.getElementById("br2");
    //Sends message to event.js (background script) telling it to disable the
    chrome.extension.sendMessage({ cmd: "setOnOffState", data: {value: isExtensionOn} });

    chrome.extension.sendMessage({ cmd: "getOnOffState"}, function(response){
        console.log(response);
        if (response == true){
            disableButton.innerHTML = "Disable";
            disableButton.className = "button button3"
            disableButton.style.display = "";
            br1.style.display = "";
            br2.style.display = "";
        }
        if (response == false){
            disableButton.innerHTML = "Enable";
            disableButton.className = "button button1"
            disableButton.style.display = "";
            br1.style.display = "";
            br2.style.display = "";
        }
    });

Ниже приведено больше кода, но это действующий код, который нельзя разделить.

Popup.html:

<button class="button button1" id="disableButton" style="display:none">Error</button>
    <br id="br1" style="display:none">
<br id="br2" style="display:none">

Background.js:

var isExtensionOn = true;

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse){
    if (request.cmd == "setOnOffState") {
        isExtensionOn = request.data.value;
    }

    if (request.cmd == "getOnOffState") {
        sendResponse(isExtensionOn);
    }
});

Любая помощь по этому поводу очень ценится!

Ответы

Ответ 1

После прохождения кода, который вы предоставили, кажется, что в коде есть тривиальные промахи, которые привели к сбою функциональности.

Я буду указывать на ошибки, которые вы сделали здесь:

  • В Popup.js переменная isExtensionOn имеет функциональную область disableButton() и, следовательно, не может быть доступна внутри document.addEventListener('DOMContentLoaded', function() { }).

    Значение isExtensionOn внутри этой функции прослушивателя будет undefined, что не является ожидаемым в вашей системе.

    Чтобы исправить это, вам просто нужно определить переменную isExtensionOn на уровне выше (например, глобальном уровне), чтобы он был доступен как для function disableButton() { }) и для прослушивателя событий DOMContentLoaded.

  • В Popup.js функциональный блок chrome.extension.sendMessage({cmd: "getOnOffState"}, function (response) { }) содержит disableButton, который, как я вижу, нигде не определен в функциональной области прослушивателя событий DOMContentLoaded. И вы выполняете задание на него, что приведет к ошибкам в консоли любого браузера, который будет выглядеть так:

    Uncaught ReferenceError: disableButton is not defined

    Чтобы устранить эту проблему, вам необходимо определить disableButton в пределах области прослушивателя событий DOMContentLoaded.

  • В Popup.js внутри прослушивателя событий DOMContentLoaded вы определили переменную singleButton как var singleButton = document.getElementById("singleButton"); , но я вижу, что в файле Popup.html, который вы предоставили, нет элемента, кроме id singleButton.

    Это вернет вам значение null, опять же это то, чего вы не ожидаете иметь в своей системе.

    Чтобы устранить эту проблему, вам необходимо исправить указанный id, например document.getElementById("disableButton"); в рамках прослушивателя событий DOMContentLoaded.

ПРИМЕЧАНИЕ. Я упоминаю некоторые соглашения, которые вы можете использовать для улучшения методов кодирования.

  1. Именование всех html файлов необходимо начинать с нижних регистров.
  2. Используйте === вместо == для строгого сравнения. Подробнее см. Здесь.
  3. Используйте правильные углубления, чтобы не пропустить никаких брекетов или совершить непреднамеренные ошибки. (Вы пропустили }) в блоке кода, где вы определили прослушиватель событий для DOMContentLoaded)

Поэтому, чтобы подвести итог, я пишу весь код всех файлов, которые вы упомянули здесь, с соответствующими исправлениями:

popup.html:

<button class="button button1" id="disableButton" style="display:none">Error</button>
<br id="br1" style="display:none">
<br id="br2" style="display:none">

Popup.js:

var isExtensionOn = true;

function disableButton() {
    var disableButton = document.getElementById("disableButton");
    if (disableButton.innerHTML === "Disable") {
        isExtensionOn = false;
    } else if (disableButton.innerHTML === "Enable") {
        isExtensionOn = true;
    } else {
        alert("Error");
    }
}

document.addEventListener('DOMContentLoaded', function () {
    var disableButton = document.getElementById("disableButton");
    var br1 = document.getElementById("br1");
    var br2 = document.getElementById("br2");

//Send message to event.js (background script) telling it to disable the extension.

    chrome.extension.sendMessage({cmd: "setOnOffState", data: {value: isExtensionOn}});

    chrome.extension.sendMessage({cmd: "getOnOffState"}, function (response) {
        if (response !== undefined) {
            if (response) {
                disableButton.innerHTML = "Disable";
                disableButton.className = "button button3";
                disableButton.style.display = "";
                br1.style.display = "";
                br2.style.display = "";
            }
            else {
                disableButton.innerHTML = "Enable";
                disableButton.className = "button button1";
                disableButton.style.display = "";
                br1.style.display = "";
                br2.style.display = "";
            }
        }
    });
});

Background.js:

chrome.runtime.onMessage.addListener(
    function (request, sender, sendResponse) {
        if (request.cmd === "setOnOffState") {
            isExtensionOn = request.data.value;
        }

        if (request.cmd === "getOnOffState") {
            sendResponse(isExtensionOn);
        }
    });

Это должно работать согласно вашему требованию. Пожалуйста, пройдите ответ и сообщите мне, если у вас возникнут другие проблемы в этом отношении.

Ответ 2

Часть скрипта, который вы предоставляете, имеет ошибку определения области видимости. См. Эту строку в событии DOMContentLoaded:

chrome.extension.sendMessage({ cmd: "setOnOffState", data: {value: isExtensionOn} });

Насколько я могу судить, в этой области нет переменной с именем isExtensionOn. Он определяется в области функций disableButton(), но не в событии. Таким образом, ваш скрипт будет указывать серверу, чтобы установить переменную в undefined.

Когда вы затем переходите к проверке значения против true и false, ни одно из них не будет значением. Это может вызвать проблему. Чтобы исправить это, измените {value: isExtensionOn} на {value: false}.

Во-вторых, вы используете кнопку с идентификатором singleButton, хотя на этом идентификаторе нет кнопки. Вы назначаете его переменной singleButton, но ниже ниже вы используете кнопку disableButton, которая не определена.

Кроме того, в вашей последней строке отсутствует закрывающая скобка: }). После исправления всех этих проблем плагин работает отлично, я его протестировал.

Совет:

Вы можете отлаживать расширение и просматривать ошибки, открыв всплывающее окно, щелкнув его правой кнопкой мыши, а затем выбрав " Inspect Element. Перейдите на вкладку консоли. В нем будут ошибки JavaScript.

Ответ 3

Всплывающее окно может получить доступ к фоновому скрипту напрямую, через chrome.runtime.getBackgroundPage, поэтому упростить его:

popup.js

var backgroundPage;
var theButton = document.querySelector("button");

function updateButton(onOrOff){
    theButton.innerHTML = onOrOff ? "Disable" : "Enable";
    theButton.className = onOrOff ? "button button3" : "button button1";
}        

function toggleButton(){
    backgroundPage.isExtensionOn = !backgroundPage.isExtensionOn;
    updateButton(backgroundPage.isExtensionOn);
}

chrome.runtime.getBackgroundPage(function(bgPage) {
    backgroundPage = bgPage;
    updateButton(bgPage.isExtensionOn);
    theButton.onclick = toggleButton;
    theButton.style.display = "";
    document.getElementById("br1").style.display = "";
    document.getElementById("br1").style.display = "";
});

//the rest of your code just needs to check backgroundPage.isExtensionOn
//to see if the extension is on or not.

popup.html

<button class="button button1" id="disableButton" style="display:none">Error</button>
<br id="br1" style="display:none">
<br id="br2" style="display:none">
<script src="popup.js"></script>

background.js

var isExtensionOn = true;  //this will be changed by popup.js directly.