Movatterモバイル変換


[0]ホーム

URL:


MDN Web Docs

Attribute reflection

Anattribute extends anHTML,XML,SVG or otherelement, changing its behavior or providing metadata.

Many attributes arereflected in the correspondingDOM interface.This means that the value of the attribute can be read or written directly in JavaScript through a property on the corresponding interface, and vice versa.The reflected properties offer a more natural programming approach than getting and setting attribute values using thegetAttribute() andsetAttribute() methods of theElement interface.

This guide provides an overview of reflected attributes and how they are used.

Attribute getter/setter

First let's see the default mechanism for getting and setting an attribute, which can be used whether or not the attribute is reflected.To get the attribute you call thegetAttribute() method of theElement interface, specifying the attribute name.To set the attribute you call thesetAttribute() methods, specifying the attribute name and new value.

Consider the following HTML:

html
<input placeholder="Original placeholder" />

To get and set theplaceholder attribute:

js
const input = document.querySelector("input");// Get the placeholder attributelet attr = input.getAttribute("placeholder");// Set the placeholder attributeinput.setAttribute("placeholder", "Modified placeholder");

Reflected attributes

For an<input> theplaceholder attribute is reflected by theHTMLInputElement.placeholder property.Given the same HTML as before:

html
<input placeholder="Original placeholder" />

The same operation can be performed more naturally using theplaceholder property:

js
const input = document.querySelector("input");// Get the placeholder attributelet attr = input.placeholder;// Set the placeholder attributeinput.placeholder = "Modified placeholder";

Note that the name of the reflected attribute and the property are the same:placeholder.This is not always the case: properties are usually named following thecamelCase convention.This is particularly true for multi-word attribute names that contain a characters that are not allowed in a property name, such as the hyphen.For example thearia-checked attribute is reflected by theariaChecked property.

Boolean reflected attributes

Boolean attributes are a little different than others in that they don't have to be declared with a name and a value.For example, the checkbox<input> element below has thechecked attribute, and will be checked on display:

html
<input type="checkbox" checked />

TheElement.getAttribute() will return"" if the input is checked ornull if it is not.The correspondingHTMLInputElement.checked property returnstrue orfalse for the checked state.Otherwise boolean reflected attributes are the same as any other reflected attributes.

Enumerated reflected attributes

In HTML,enumerated attributes are attributes with a limited, predefined set of text values. For example, the global HTMLdir attribute has three valid values:ltr,rtl, andauto.

html
<p dir="rtl">Right to left</p>

Like for HTML tag names, HTML enumerated attributes and their values are case-insensitive, soLTR,RTL, andAUTO will also work.

html
<p dir="RTL">Right to left</p>

The IDL-reflected property,HTMLElement.dir, always returns a canonical value as provided in the specification (lowercased values in this example). Setting the value also serializes it to the canonical form.

js
const pElement = document.querySelector("p");console.log(pElement.dir); // "rtl"pElement.dir = "RTL";console.log(pElement.dir); // "rtl"

Alternatively, you can use thegetAttribute() method of theElement interface. It will get the attribute value from HTML without modifications.

js
const pElement = document.querySelector("p");console.log(pElement.getAttribute("dir"); // "RTL"

Reflected element references

Note:This section applies toreflected ARIA attributes that contain element references.The same considerations are likely to apply to other/future attributes that reflect element references.

Some attributes take elementreferences as values: either an elementid value or a space-separated string of elementid values.Theseid values refer to other elements which are related to the attribute, or that contain information needed by the attribute.These attributes are reflected by a corresponding property as an array ofHTMLElement-derived object instances that match theid values, with some caveats.

For example, thearia-labelledby attribute lists theid values of elements that contain the accessible name for an element in their inner text.The HTML below shows this for an<input> that has a label defined in<span> elements withid values oflabel_1,label_2, andlabel_3:

html
<span>(Label 1 Text)</span><span>(Label 2 Text)</span><input aria-labelledby="label_1 label_2 label_3" />

This attribute is reflected byElement.ariaLabelledByElements property, which returns the array of elements that have the correspondingid values.The attribute and corresponding property can be returned as shown:

js
const inputElement = document.querySelector("input");console.log(inputElement.getAttribute("aria-labelledby"));// "label_1 label_2 label_3"console.log(inputElement.ariaLabelledByElements);// [HTMLSpanElement, HTMLSpanElement]

The first thing to note from the code above is that the attribute and the property contain different numbers of elements — the property doesn'tdirectly reflect the attribute because the referencelabel_3 does not have a corresponding element.It is also possible that a reference will not match because theid isout of scope for the element.This can happen if the referenced element is not in the same DOM or shadow DOM as the element, since ids are only only valid in the scope in which they are declared.

We can iterate the elements in the property array, in this case to get the accessible name from their inner text (this is more natural than using the attribute, because we don't have to first get the element references and then use them to find the elements, and we only have to work with elements that we know to be available in the current scope):

js
const inputElement = document.querySelector("input");const accessibleName = inputElement.ariaLabelledByElements  .map((e) => e.textContent.trim())  .join(" ");console.log(accessibleName);// (Label 1 Text) (Label 2 Text)

Setting the property and attribute

For normal reflected properties, updates to the property are reflected in the corresponding attribute and vice versa.For reflected element references this is not the case.Instead, setting the property clears (unsets) the attribute, so that the property and attribute no longer reflect each other.For example, given the following HTML:

html
<span>(Label 1 Text)</span><span>(Label 2 Text)</span><input aria-labelledby="label_1 label_2" />

The initial value of thearia-labelledby is"label_1 label_2", but if we set it from the DOM API, the attribute is reset to"":

js
const inputElement = document.querySelector("input");let attributeValue = inputElement.getAttribute("aria-labelledby");console.log(attributeValue);// "label_1 label_2"// Set attribute using the reflected propertyinputElement.ariaLabelledByElements = document.querySelectorAll("span");attributeValue = inputElement.getAttribute("aria-labelledby");console.log(attributeValue);// ""

This makes sense because you could otherwise assign elements to the property that don't have anid reference, and hence can't be represented in the attribute.

Setting the attribute value restores the relationship between the attribute and the property.Continuing the example from above:

js
inputElement.setAttribute("aria-labelledby", "input1");attributeValue = inputElement.getAttribute("aria-labelledby");console.log(attributeValue);// "label_1"// Set attribute using the reflected propertyconsole.log(inputElement.ariaLabelledByElements);// [HTMLSpanElement] - for `label_1`

The array returned by the property is static, so you can't modify the returned array to cause changes to the corresponding attribute.When an array is assigned to the property it is copied, so any changes to the attribute will not be reflected in a previously returned property array.

Element id reference scope

Attribute element references can only refer to other elements that are in the same DOM orShadow DOM, because element ids are only valid in the scope in which they are declared.

We can see this in the following code.Thearia-labelledby attribute of the<input> element references the elements with idslabel_1,label_2, andlabel_3.Howeverlabel_3 is not a valid id in this case because it is not defined in the same scope as the<input> element.As a result the label will only come from the elements with idslabel_1 andlabel_2.

html
<div>  <span>(Label 3 Text)</span></div><div>  <template shadowrootmode="open">    <span>(Label 1 Text)</span>    <input aria-labelledby="label_1 label_2 label_3" />    <span>(Label 2 Text)</span>  </template></div>

Reflected element reference scope

When using theinstance properties reflected from ARIA element references, such asElement.ariaLabelledByElements foraria-labelledby, the scoping rules are a little different.To be in scope a target element must be in the same DOM as the referencing element, or a parent DOM.Elements in other DOMs, including shadow DOMs that are children or peers of the referring DOM, are out of scope.

The example below shows the case where an element in a parent DOM (label_3) is set as a target, along with the elements with idslabel_1 andlabel_2 which are declared in the same shadow root.This works because all the target elements are in scope for the referencing element.

html
<div>  <span>(Label 3 Text)</span></div><div>  <template shadowrootmode="open">    <span>(Label 1 Text)</span>    <input />    <span>(Label 2 Text)</span>  </template></div>
js
const host = document.getElementById("host");const input = host.shadowRoot.getElementById("input");input.ariaLabelledByElements = [  host.shadowRoot.getElementById("label_1"),  host.shadowRoot.getElementById("label_2"),  document.getElementById("label_3"),];

The equivalent code with an element in the DOM referencing another in the shadow DOM would not work, because target elements that are in nested shadow DOMs are not in scope:

html
<div>  <span>(Label 1 Text)</span>  <input />  <span>(Label 2 Text)</span></div><div>  <template shadowrootmode="open">    <span>(Label 3 Text)</span>  </template></div>
js
const host = document.getElementById("host");const input = document.getElementById("input");input.ariaLabelledByElements = [  host.shadowRoot.getElementById("label_3"),  document.getElementById("label_1"),  document.getElementById("label_2"),];

Note that an element may initially be "in scope" and then moved out of scope into a nested shadow root.In this case the referenced element will still be listed in the attribute, but will not be returned in the property.Note however that if the element is moved back into scope, it will again be present in the reflected property.

Summary of the attribute/property relationship

The relationship between attributes containing element references and their corresponding property is as follows:

  • Attribute elementid references are onlyin-scope for target elements declared in the same DOM or shadow DOM as the element.
  • Properties that reflect ARIA element references can target elements in the same scope or a parent scope. Elements in nested scopes are not accessible.
  • Setting the property clears the attribute and the property and attribute no longer reflect each other.If the attributes is read, withElement.getAttribute(), the value is"".
  • Setting the attribute, withElement.setAttribute(), also sets the property and restores the "reflection relationship".
  • Setting the attribute with a value reference that is subsequently moved out of scope will result in removal of the corresponding element from the property array.Note however that the attribute still contains the reference, and if the element is moved back in-scope the property will again include the element (i.e., the relationship is restored).

Help improve MDN

Learn how to contribute.

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp