Изменение документа
Основными средствами изменения документа являются:
Добавление в DOM новых узлов (элементов) — element_1.appendChild(element_2) — и удаление существующих — .remove(element); изменение порядка узлов — insertBefore(element_1, element_2) и замена одного узла другим — element_1.replaceChild(element_1, element_3).
Присвоение атрибута элементу, изменение значения атрибута элемента и удаление атрибута.
Основными методами здесь являются
element.setAttribute(attribute_name, attribute_value),
результат вызова которого эквивалентен element.attribute=attribute_value, и
element.removeAttribute(attribute_name)
В первую очередь это относится к атрибуту style; как и другие он может быть удален, перезаписан (element.style=text; element.style.cssText=text), но кроме того, изменению подлежат и отдельные свойства объекта element.style, соответствующие стилевым свойствам элемента. Заметим, что element.cssText можно свободно оперировать как строковым значением (так, element.cssText+='property:value' добавит новое стилевое свойство или перезапишет существующее.).
Один элемент может заимствовать стилевое оформление другого посредством element_1.style.cssText=element_2.style.cssText. Манипулируя такими свойствами как display, opacity, z-index, visibility (при определенном позиционировании элемента), размерами (при overflow:hidden) и положением (при overflow:hidden для родителя) возможно добиться того, чтобы элемент не отображался на странице — создать иллюзию его отсутствия, хотя он попрежнему включён в структуру документа.
Анатомия объекта style
Справа показан код, запуск которого позволяет просмотреть все свойства объекта style
(в центре) для стилизованного HTML-элемента (слева).
Хорошо видно, что декларации вроде border-radius:50% представляют собой сокращённый способ задания сразу нескольких стилевых свойств.
Особого внимания заслуживает изменение атрибута src тега <img>. [дополняется]
Операции с селекторами CSS: Добавление для элемента новых классов, исключение его из тех, к которым он относится, присвоение элементу id и удаление идентификатора (эти операции могут осуществляться посредством изменения атрибутов, но мы рассмотрим их отдельно). Цель этих манипуляций обычно состоит в том, что соответствующему элементу автоматически присваиваются (либо удаляются) стилевые свойства, заданные для селектора; но иногда создаются классы без каких-либо стилевых правил, и удаление либо добавление атрибута такого класса упрощает оперирование элементом, определяя принадлежность его некоторому массиву.
Наконец, HTML кодом элемента можно оперировать как строковым значением; содержимое элемента может быть изменено произвольным образом: полностью заменено (в т. ч. на пустое) или дополнено — с помощью команд element.innerHTML+=content, element.innerHTML=content+element.innerHTML или же метода insertAdjacentHTML.
Заметим, что процессы, запускаемые в браузере командами element. innerHTML+=content и element.insertAdjacentHTML ('beforeend', content) (соответственно element. innerHTML=content+element.innerHTML и element.insertAdjacentHTML ('afterbegin', content)), не тождественны: первый состоит в удалении всех конструкций, в т. ч. замещаемых элементов, определяемых прежним HTML,
и реализации браузером нового кода 'с нуля', тогда как второй состоит в отображении браузером дополнительного содержимого с сохранением существующего.
Простой пример демонстрирует, какие недоразумения могут вознинуть, если не учитывать это обстоятельство.
Более того, узел может быть полностью заменен посредством присвоения атрибуту DOM-интерфейса элемента .outerHTML нового HTML-кода в виде строкового значения (в частности, при присвоении в качестве значения пустой строки: element.outerHTML='' — элемент будет удален.)
Ниже приведен простой код, позволяющий для заданного узла или документа в целом найти все дочерние элементы с заданным тегом и присвоить им другой тег с сохранением содержимого:
function substitute(parent, tag_1, tag_2) {
const selected = Array.from(parent.getElementsByTagName(tag_1));
for (let el of selected) {
el.outerHTML = '<' + tag_2 + '>' + el.innerHTML + '' + tag_2 + '>'
}
};
//substitute(document.body, 'p', 'h1')
Для глобальных изменений оформления страницы можно также отключать и подключать целые таблицы стилей [дополняется].
Объектная модель CSS.
Каждая отдельная таблица стилей CSS представлена объектом StyleSheet, имеющим ряд свойств, доступных (за исключением свойства disabled) только для чтения. Интерфейс StyleSheet не отражает внутренней структуры таблицы стилей.
Объект CSSStyleSheet наследует свойства от StyleSheet и при этом располагает рядом собственных свойств, которые и отображают структуру таблицы стилей. Интерфейс CSSStyleSheet предоставляет методы, позволяющие добавлять и удалять отдельные стилевые правила.
Напомним, что таблица стилей представляет собой упорядоченный перечень правил, каждое из которых состоит из селектора и блока объявлений, распадающего в свою очередь на пары свойство — значение.
Соответственно, свойство cssRules объекта CSSStyleSheet содержит живую коллекцию объектов, каждый из которых представляет отдельное CSS-правило, и имеет следующие свойства:
selectorText, содержащее строковое значение, соответствующее селектору (простому или сложному);
style — объект, соответствующий блоку объявлений стилевых свойств. style в свою очередь имеет свойства, соответствующие стилевым и принимающие строковые значения.
document.styleSheets представляет собой коллекцию (массивоподобный объект), состоящую из экземпляров CSSStyleSheet, моделирующих все стилевые таблицы, подключенные к документу (как встроенные, так и внешние).
Следующий код демонстрирует возможности перечисленных объектов и их методов на примере функции,
принимающей три аргумента со строковыми значениями — CSS-селектор, имя свойства (затеметим, что здесь не требуется перевод в "верблюжью" нотацию!) и имя нового значения —
и изменяющая для данного селектора значение свойства на заданное во всех стилевых таблицах, действующих на страницу:
function changeRule(selector, prop, newval) {
for (let ss of document.styleSheets) {
if (ss.type == "text/css") {
for (let rule of ss.cssRules) {
if (rule.type == CSSRule.STYLE_RULE && rule.selectorText == selector) {
rule.style[prop] = newval
}
}
}
}
}