Attributes and Properties
Attributes and Properties (属性和属性)
In HTML, you can write, declare elements, and pass values in attributes. In JavaScript, particularly in DOM, there are properties available while querying HTML elements via the DOM. (在HTML中,您可以编写、声明元素并在属性中传递值。在JavaScript中,特别是在DOM中,当通过DOM查询HTML元素时,有可用的属性。)
In this chapter, the attributes, and properties of JavaScript are covered. (本章将介绍JavaScript的属性和属性。)
DOM Properties
DOM Properties (DOM属性)
JavaScript DOM objects have properties. They are like instance variables for the particular element. There exist different types of properties, such as string, boolean and more). You can access them using the prop method of jQuery, as well as by interacting with a vanilla JS object. (JavaScript DOM对象具有属性。它们就像特定元素的实例变量。存在不同类型的属性,例如字符串、布尔值等)。您可以使用jQuery的prop方法以及通过与vanilla JS对象交互来访问它们。)
Here is an example of using the prop method:
<a href='https://www.w3cdoc.com' class='linkClasses' name='linkName' id='linkId'>Welcome</a>
$('#linkId').prop('href'); // returns "http://example.com/page.html"
$('#linkId').prop('name'); // returns "linkName"
$('#linkId').prop('id'); // returns "linkId"
$('#linkId').prop('className'); // returns "linkClasses"
We have already learned that DOM nodes are considered regular JavaScript objects. So, they can be altered. (我们已经了解到, DOM节点被视为常规JavaScript对象。因此,它们是可以改变的。)
For example, let’s try to create a new property in document.body, like here:
document.body.myData = {
name: 'w3cdoc',
bookTitle: 'Javascript'
};
console.log(document.body.myData.bookTitle); // Javascript
A method can also be added, as follows:
document.body.sayTagName = function () {
console.log(this.tagName);
};
document.body.sayTagName(); // BODY,the value of "this" in the method is document.body
Also, you can modify built-in prototypes, such as Element.prototype , adding new methods to all the elements, like this:
Element.prototype.welcome = function () {
console.log(`Welcome to ${this.tagName}`);
};
document.documentElement.welcome(); // Welcome to HTML
document.body.welcome(); // Welcome to BODY
So, it can be stated that the properties and methods of DOM are similar to regular objects in JavaScript. (因此,可以说DOM的属性和方法类似于JavaScript中的常规对象。)
HTML Attributes
HTML Attributes (HTML属性)
Attributes are in the HTML itself. They are similar to properties. But when a property is available, it would be best if you worked with properties rather than attributes. (属性在HTML本身中。它们与属性相似。但是,当属性可用时,最好使用属性而不是属性。)
So, HTML tags can have attributes. At the time the browser parses the HTML for creating DOM objects with tags, it accepts standard attributes, creating DOM properties for them. (因此, HTML标记可以具有属性。当浏览器解析HTML以创建带有标记的DOM对象时,它接受标准属性,并为它们创建DOM属性。)
When an element has an id or another standard attribute, the matching property is generated. But, if the attribute is not standard, it will not take place. (当元素具有id或其他标准属性时,将生成匹配属性。但是,如果属性不标准,则不会发生。)
Here is an example of using a non-standard attribute:
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
</head>
<body id="bodyId" something="non-standard">
<script>
alert(document.body.id); // bodyId
// non-standard attribute doesn’t yield a property
(//非标准属性不生成属性)
alert(document.body.something); // undefined
</script>
</body>
</html>
Also, take into account that a standard attribute for one element may be unknown for another one. For example, “type” is standard for , <input> , but never for , <body>.
The standard attributes can be described in the specification for the matching element class, as follows:
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
</head>
<body id="body" type="...">
<input id="input" type="text">
<script>
alert(input.type); // text
alert(body.type); // undefined: DOM property not created, because it's non-standard
</script>
</body>
</html>
If an attribute is not standard, there will be no DOM property for it. However, all the attributes are accessible while implementing the following methods:
For checking the existence-elem.hasAttribute(name). (-用于检查existence-elem.hasAttribute (name)。)
For getting the value-elem.getAttribute(name). (-用于获取value-elem.getAttribute (name)。)
For setting the value- elem.setAttribute(name, value). (-用于设置值- elem.setAttribute (name, value)。)
For removing the attribute- elem.removeAttribute(name). (-用于删除attribute- elem.removeAttribute (name)。)
It is also possible to read the attributes using elem.attributes: a group of objects that belong to a built-in class Attr, along with name and value properties. The illustration of reading a non-standard property is the following:
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
</head>
<body something="non-standard">
<script>
alert(document.body.getAttribute('something')); // non-standard
</script>
</body>
</html>
The features of HTML attributes are as follows:
Their name is considered case-insensitive (id and ID are the same). (-其名称不区分大小写( ID和ID相同)。)
Their values are strings. (-他们的价值观是字符串。)
The example of working with attributes looks like this:
// create div
let div = document.createElement("div");
div.id = 'elem';
div.setAttribute('about', "w3cdoc");
document.body.appendChild(div);
console.log(div.getAttribute('About')); // (1) 'w3cdoc', reading
div.setAttribute('Test', 100); // (2), writing
alert(div.outerHTML); // (3), see if the attribute is in HTML (yes)
for (let attr of div.attributes) { // (4) list all
console.log(`${attr.name} = ${attr.value}`);
}
Please, note that in getAttribute(‘About’) the first letter is uppercase. In HTML, it’s all lowercase. Anyway, the names of attributes are case-insensitive. Anything can be assigned to attributes, but it becomes a string. All the attributes are visible in outerHTML. The collection of attributes is iterable and has all the attributes of the element (both standard and non-standard) like objects with name and value properties. (请注意,在getAttribute (‘About’)中,第一个字母为大写。在HTML中,全部为小写。无论如何,属性的名称不区分大小写。任何内容都可以分配给属性,但它会变成一个字符串。所有属性在outerHTML中都可见。属性集合是可迭代的,并且具有元素的所有属性(标准和非标准) ,如具有名称和值属性的对象。)
Property-Attribute Synchronization
Property-Attribute Synchronization (属性-属性同步)
Whenever a standard attribute changes, the matching property is auto-updated, and vice versa. (每当标准属性更改时,匹配属性都会自动更新,反之亦然。)
In the case below, id may be modified as an attribute, and you can also see the property changed, as well. Here is the backward situation:
// create input
let inp = document.createElement("input");
document.body.appendChild(inp);
let input = document.querySelector('input');
// attribute => property
input.setAttribute('id', 'inputId');
console.log(input.id); // inputId
// property => attribute
input.id = 'newInputId';
console.log(input.getAttribute('id')); // newInputId (updated)
Of course, there are exceptions, such as input.value synchronizes from attribute to property, but not the opposite way:
// create input
let inp = document.createElement("input");
document.body.appendChild(inp);
let input = document.querySelector('input');
// attribute => property
input.setAttribute('value', 'text');
console.log(input.value); // text
// NOT property => attribute
input.value = 'newValue';
console.log(input.getAttribute('value')); // text (not updated)
So, in the case above, changing the value of the attribute updates the property. However, the property change will not affect the attribute. (因此,在上述情况下,更改属性的值会更新属性。但是,属性更改不会影响属性。)
The given feature is useful, as the user actions might lead to value changes. Then, if you wish to recover the original value from HTML, it will be in the attribute. (给定的功能很有用,因为用户操作可能会导致值更改。然后,如果您希望从HTML恢复原始值,它将位于属性中。)
DOM Properties are Typed
DOM Properties are Typed (已键入DOM属性)
The properties of DOM are not always strings. For example, the input.checked property is considered a boolean:
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
</head>
<body>
<input id="input" type="checkbox" checked> checkbox
<script>
alert(input.getAttribute('checked')); // the attribute value is: empty string
alert(input.checked); // the property value is: true
</script>
</body>
</html>
And the same thing in javascript:
// create input
let inp = document.createElement("input");
inp.id = 'input';
document.body.appendChild(inp);
let input = document.querySelector('input');
input.setAttribute('type', 'checkbox');
document.getElementById("input").checked = true;
console.log(input.getAttribute('checked')); // the attribute value is: empty string
console.log(input.checked); // the property value is: true
Let’s check out another example. The style attribute is a string, but the style property is an object, like here:
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
</head>
<body>
<div id="div" style="color:green; font-size:150%">Welcome</div>
<script>
// string
(字符串)
alert(div.getAttribute('style')); // color:green; font-size:80%
// object
(对象)
alert(div.style); // [object CSSStyleDeclaration]
alert(div.style.color); // green
</script>
</body>
</html>
And the same thing in javascript:
let div = document.createElement("div");
div.id = 'elem';
div.setAttribute('style', "color:green; font-size: 150%");
div.innerHTML = 'Welcome to w3cdoc';
document.body.appendChild(div);
// string
alert(elem.getAttribute('style')); // color:green;font-size:150%
// object
alert(elem.style); // [object CSSStyleDeclaration]
alert(elem.style.color); // green
Most properties are strings. Even if a property type of DOM is a string, it can differ from the attribute. For example, the href DOM property is always a full URL, even though the attribute includes a relative URL or a #hash.
Let’s check out an example:
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
</head>
<body>
<a id="a" href="#welcome">link</a>
<script>
// attribute
(属性)
alert(a.getAttribute('href')); // #welcome
// property
(物业)
alert(a.href ); // full URL in the form http://site.com/page#welcome
</script>
</body>
</html>
And the same thing in javascript:
let a = document.createElement('a');
let link = document.createTextNode("Link");
a.appendChild(link);
a.id = 'a';
a.title = "Link";
a.href = "#welcome";
document.body.appendChild(a);
// attribute
console.log(a.getAttribute('href')); // #welcome
// property
console.log(a.href); // full URL in the form http://site.com/page#welcome
In case you need the value of href or any other attribute as it’s written in HTML, getAttribute might be used. (如果您需要href或任何其他属性的值,因为它是用HTML编写的,则可以使用getAttribute。)
Non-standard Attributes
Non-standard Attributes (标准属性)
While writing HTML, there are many standard attributes to use. As for the non-standard ones, let’s discover when they can come handy. (编写HTML时,有许多标准属性可供使用。至于非标准的,让我们来看看它们什么时候可以派上用场。)
At times, non-standard attributes are implemented for passing custom data from HTML to JavaScript, or for marking HTML elements for JavaScript. It is demonstrated in the example below:
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
</head>
<body>
<a id="a" href="#welcome">link</a>
<script>
// attribute
(属性)
alert(a.getAttribute('href')); // #welcome
// property
(物业)
alert(a.href ); // full URL in the form http://site.com/page#welcome
</script><!-- mark the div to show "siteName" here -->
<div show-info="siteName"></div>
<!-- and "bookName" here -->
<div show-info="bookName"></div>
<script>
// code finds the marked item and shows what is requested
let site = {
siteName: "w3cdoc",
bookName: "Javascript"
};
for(let div of document.querySelectorAll('[show-info]')) {
// insert the corresponding info into the field
(//将相应的信息插入字段)
let field = div.getAttribute('show-info');
div.innerHTML = site[field]; // first w3cdoc into "siteName", then Javascript into "bookName"
}
</script>
</body>
</html>
And the same thing in javascript:
let div1 = document.createElement("div");
div1.setAttribute('show-info', "siteName");
document.body.appendChild(div1);
let div2 = document.createElement("div");
div2.setAttribute('show-info', "bookName");
document.body.appendChild(div2);
let site = {
siteName: "w3cdoc",
bookName: "Javascript"
};
for (let div of document.querySelectorAll('[show-info]')) {
let attr = div.getAttribute('show-info');
div.innerHTML = site[attr]; // first w3cdoc into "siteName", then Javascript into "book Name"
}
They can also be used for styling an element. The attribute order-state is used, for the order state, as shown in the example below:
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
<style>
/* "styles depend on the custom attribute "order status" */
(/* "样式取决于自定义属性"订单状态"*/)
.order[order-state="new"] {
color: red;
}
.order[order-state="pending"] {
color: green;
}
.order[order-state="canceled"] {
color: blue;
}
</style>
</head>
<body>
<div class="order" order-state="new">
New order.
(新指令)
</div>
<div class="order" order-state="pending">
Pending order.
(Pending订单)
</div>
<div class="order" order-state="canceled">
Canceled order.
(已取消的订单。)
</div>
</body>
</html>
Now, let’s see why using an attribute is preferable to having classes like .order-state-new, .order-state-pending, . order-state-canceled. (现在,让我们来看看为什么使用属性比.order-state-new、.order-state-pending、. order-state-canceled等类更可取。)
As an attribute is handier to manage. The state may be changed as easy as here:
// removing old/adding a new class
div.setAttribute('order-state', 'canceled');
Possibly, there can be a problem with custom attributes. The HTML language continuously grows, and more attributes suit the needs of developers. But, unexpected effects may occur in such cases. So, for avoiding conflicts, data-* attributes exist. (可能是自定义属性有问题。HTML语言不断发展,更多属性满足开发人员的需求。但是,在这种情况下可能会发生意想不到的影响。因此,为了避免冲突,存在data- *属性。)
All the attributes, starting with “data-” are stocked for developers’ use. They are in the dataset property. For example, if an elem has got an attribute, called “data-about”, it may be available as elem.dataset.about, as follows:
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
</head>
<body data-about="w3cdoc">
<script>
alert(document.body.dataset.about); // w3cdoc
</script>
</body>
</html>
Multiword attributes, such as data-order-state have become dataset.orderState. (多词属性(如data-order-state )已变为dataset.orderState。)
Here is an “order state” example rewritten:
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
<style>
.order[data-order-state="new"] {
color: red;
}
.order[data-order-state="pending"] {
color: green;
}
.order[data-order-state="canceled"] {
color: blue;
}
</style>
</head>
<body>
<div id="order" class="order" data-order-state="new">
New order.
(新指令)
</div>
<script>
// read
(已读)
(order.dataset.orderState); // new
// modify
(修改)
order.dataset.orderState = "pending"; // (*)
</script>
</body>
</html>
It is valid to use data-* attribute: a safe way of passing custom data.
Also, it would be best if you took into consideration that you can both read and modify data attributes. The CSS will update the view accordingly. (此外,最好考虑可以读取和修改数据属性。CSS将相应地更新视图。)
Summary
Summary (概要)
So, properties are like instance variables for the specific element. They can be of different types (booleans, strings and more). Attributes are similar to properties, but are not considered good enough. They are in the HTML, rather than in the DOM. Attributes are particularly useful when one wants to set a custom attribute ( when no property is associated). (因此,属性类似于特定元素的实例变量。它们可以是不同类型(布尔值、字符串等)。属性与属性相似,但被认为不够好。它们在HTML中,而不是在DOM中。当想要设置自定义属性时(当没有关联属性时) ,属性特别有用。)
To be brief, attributes are written in HTML, while properties are in the DOM objects. (简而言之,属性是用HTML编写的,而属性是在DOM对象中。)
In most cases, using properties is preferable. As it was mentioned, attributes should be referred to when DOM properties don’t suit when you need exact attributes. For instance, when a non-standard attribute is necessary. But, in case it starts with data-, then dataset should be used. Another example is when you want to read the value “as written” in the HTML. The DOM property value can be different: the href property is always a full URL, and you may wish to get the original value.