Изменение документа
Основными средствами изменения документа являются:
Добавление в 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
}
}
}
}
}