Вы можете многое сделать с интерфейсом Window в браузере. По данным МДН,

«Интерфейс Window представляет собой окно, содержащее документ DOM… Интерфейс Window содержит множество функций, пространств имен, объектов и конструкторов, которые не обязательно напрямую связаны с концепцией окна пользовательского интерфейса».

Например, предположим, что мы хотим изменить стиль для всех элементов на веб-странице, чтобы реализовать светлый/темный режим. Хотя мы могли бы пройтись по всем узлам DOM и соответствующим образом обновить их CSS, мы могли бы так же легко использовать немного JavaScript для манипулирования интерфейсом окна браузера для достижения того же результата. Как? Давайте взглянем.

Предположим, у нас есть простая HTML-страница с текстом и кнопкой с текстом «Dark» и идентификатором «dark_light». Мы начнем с добавления прослушивателя событий к кнопке на странице, а затем напишем базовый IIFE (немедленно вызываемое функциональное выражение) в обратном вызове нашего прослушивателя событий. Вы также можете использовать регулярное функциональное выражение, но здесь хорошо работает IIFE, поскольку мы хотим, чтобы функция вызывалась только один раз при вызове обратного вызова прослушивателя событий. Мы передадим глобальный объект Window браузера в качестве аргумента IIFE, чтобы мы могли изменить его позже:

document.querySelector('#dark_light').addEventListener('click', changeColor);

function changeColor() {
    (function (window) {
          })(window);
};

Далее, давайте выберем узел ‹head› документа и добавим новый узел ‹style›. По сути, это создает новый CSSStyleSheet, который позволит нам вставлять новые правила CSS:

function changeColor() {
    (function (window) {
        let style = document.querySelector("head")
        .appendChild(document.createElement("style"))
      })(window);
};

Затем объявите переменную, содержащую только что созданный CSSStyleSheet, который мы хотим изменить, обратившись к объекту StyleSheetList документа (document.styleSheets). Для этого мы будем использовать document.styleSheets[document.styleSheets.length — 1], так как мы хотим манипулировать последней (последней добавленной) таблицей стилей в общем списке StyleSheetList документа:

function changeColor() {
    (function (window) {
        let style = document.querySelector("head")
        .appendChild(document.createElement("style"))

        let styleSheet = document.styleSheets[document.styleSheets.length - 1]
      })(window);
};

Затем мы вставим новое правило CSS в CSSStyleSheet, который мы создали выше, используя встроенный метод JavaScript insertRule(). Согласно MDN, функция insertRule() принимает два аргумента: во-первых, создаваемое правило CSS, а во-вторых, позиция вновь вставленного правила в CSSStyleSheet, который мы модифицируем (второй аргумент является необязательным и по умолчанию будет равен 0, если нет). предоставил). Давайте добавим новое правило в первую позицию, используя универсальный селектор CSS:

function changeColor() {
    (function (window) {
        let style = document.querySelector("head")
        .appendChild(document.createElement("style"))

        let styleSheet = document.styleSheets[document.styleSheets.length - 1]
        styleSheet.insertRule("* {}", 0)
      })(window);
};

Теперь давайте воспользуемся свойством CSSStyleSheet cssRules, чтобы добавить новое свойство в глобальный объект Window, которое будет содержать созданное выше правило CSS:

function changeColor() {
    (function (window) {
        let style = document.querySelector("head")
        .appendChild(document.createElement("style"))

        let styleSheet = document.styleSheets[document.styleSheets.length - 1]
        styleSheet.insertRule("* {}", 0)

        window.universal = styleSheet.cssRules
      })(window);
};

Поскольку мы хотим, чтобы кнопка функционировала как тумблер включения/выключения, мы создадим условный оператор if/else после IIFE в нашей функции обратного вызова changeColor. Затем добавьте некоторые свойства CSS к правилу CSS, которое мы создали в IIFE и добавили к глобальному объекту Window. Для этого мы будем использовать window.universal[0], так как мы добавили правило в первую позицию соответствующего CSSStyleSheet через второй параметр метода insertRule(). Пока мы это делаем, давайте перевернем текст кнопки при нажатии:

function changeColor() {
    (function (window) {
        let style = document.querySelector("head")
        .appendChild(document.createElement("style"))

        let styleSheet = document.styleSheets[document.styleSheets.length - 1]
        styleSheet.insertRule("* {}", 0)

        window.universal = styleSheet.cssRules
      })(window);
if (document.querySelector('#dark_light').textContent === "Dark") {
        window.universal[0].style.backgroundColor = 'black'
        window.universal[0].style.color = 'white'
        document.querySelector('#dark_light').textContent = "Light"
    } else {
        window.universal[0].style.backgroundColor = 'white’
        window.universal[0].style.color = 'black'
        document.querySelector('#dark_light').textContent = "Dark"
    }
};

Вот и все! Также важно отметить, что этот подход повлияет только на указанные стили (цвет фона и текста выше) — все остальные CSS в отдельных таблицах стилей останутся незатронутыми.