介绍
在本系列的前一教程“ 如何更改DOM ”中,我们介绍了如何使用内置方法创建,插入,替换和从文档对象模型(DOM)中移除元素。 通过提高操作DOM的熟练程度,您可以更好地利用JavaScript的交互功能并修改Web元素。
在本教程中,我们将学习如何通过修改HTML元素节点的样式,类和其他属性来进一步改变DOM。 这将使您更好地理解如何操作DOM中的基本元素。
审查选择元素
直到最近,名为jQuery的流行JavaScript库最常用于选择和修改DOM中的元素。 jQuery简化了选择一个或多个元素并同时将更改应用于所有元素的过程。 在“ 如何访问DOM中的元素 ”中,我们回顾了在香草JavaScript中获取和使用节点的DOM方法。
要查看, document.querySelector()
和document.getElementById()
是用于访问单个元素的方法。 在下面的例子中使用带id
属性的div
,我们可以以任何方式访问该元素。
<div id="demo-id">Demo ID</div>
querySelector()
方法更健壮,因为它可以通过任何类型的选择器来选择页面上的元素。
// Both methods will return a single element
const demoId = document.querySelector('#demo-id');
访问单个元素时,我们可以轻松更新元素的一部分,例如里面的文本。
// Change the text of one element
demoId.textContent = 'Demo ID text updated.';
但是,当通过一个通用选择器(如特定类)访问多个元素时,我们必须遍历列表中的所有元素。 在下面的代码中,我们有两个具有公共类值的div
元素。
<div class="demo-class">Demo Class 1</div>
<div class="demo-class">Demo Class 2</div>
我们将使用querySelectorAll()
来获取应用了demo-class
所有元素,并forEach()
来遍历它们并应用更改。 也可以使用querySelectorAll()
以与数组相同的方式访问特定元素 - 使用括号表示法。
// Get a NodeList of all .demo elements
const demoClasses = document.querySelectorAll('.demo-class');
// Change the text of multiple elements with a loop
demoClasses.forEach(element => {
element.textContent = 'All demo classes updated.';
});
// Access the first element in the NodeList
demoClasses[0];
这是从jQuery进入到vanilla JavaScript时要注意的最重要的区别之一。 很多修改元素的例子都不能解释将这些方法和属性应用于多个元素的过程。
本文中的属性和方法通常会附加到事件监听器以响应点击,悬停或其他触发器。
注意:方法getElementsByClassName()
和getElementsByTagName()
将返回无法访问querySelectorAll()
具有的forEach()
方法的HTML集合。 在这些情况下,您将需要使用标准遍历集合。
修改属性
属性是包含有关HTML元素的附加信息的值。 它们通常以名称/值对形式出现,根据元素的不同,它们可能是必不可少的。
一些最常见的HTML属性是img
标签的src
属性,标签, class
, id
和style
的href
。 有关HTML属性的完整列表,请查看Mozilla开发者网络上的属性列表 。 不属于HTML标准的自定义元素将被添加data-
。
在JavaScript中,我们有四种修改元素属性的方法:
方法 | 描述 | 例 |
---|---|---|
hasAttribute() |
返回true 或false 布尔值 |
element.hasAttribute('href'); |
getAttribute() |
返回指定属性的值或null |
element.getAttribute('href'); |
setAttribute() |
添加或更新指定属性的值 | element.setAttribute('href', 'index.html'); |
removeAttribute() |
从元素中删除一个属性 | element.removeAttribute('href'); |
我们创建一个带有一个属性的img
标签的新HTML文件。 我们将链接到通过网址提供的公开图片,但是如果您正在离线工作,则可以将其替换为备用本地图片。
<!DOCTYPE html>
<html lang="en">
<body>
<img src="https://www.youcl.com/uploads/shark.png">
</body>
</html>
将上述HTML文件加载到现代Web浏览器并打开内置的Developer Console时 ,应该会看到如下所示的内容:
现在,我们可以即时测试所有的属性方法。
// Assign image element
const img = document.querySelector('img');
img.hasAttribute('src'); // returns true
img.getAttribute('src'); // returns "...shark.png"
img.removeAttribute('src'); // remove the src attribute and value
此时,您将删除与img
关联的src
属性和值,但您可以重置该属性并使用img.setAttribute()
将值分配给替代图像:
img.setAttribute('src', 'https://www.youcl.com/uploads/octopus.png');
最后,我们可以通过为属性指定一个新的值作为元素的属性来直接修改属性,将src
设置回shark.png
文件
img.src = 'https://www.youcl.com/uploads/shark.png';
任何属性都可以通过上述方法进行编辑。
hasAttribute()
和getAttribute()
方法通常用于条件语句 ,而setAttribute()
和removeAttribute()
方法用于直接修改DOM。
修改类
类属性对应于CSS类选择器 。 这不要与ES6类混淆, ES6类是一种特殊类型的JavaScript函数。
CSS类用于将样式应用于多个元素,而不像每个页面只能存在一次的ID。 在JavaScript中,我们有className
和classList
属性来处理class属性。
方法/属性 | 描述 | 例 |
---|---|---|
className |
获取或设置类的值 | element.className; |
classList.add() |
添加一个或多个类的值 | element.classList.add('active'); |
classList.toggle() |
打开或关闭课程 | element.classList.toggle('active'); |
classList.contains() |
检查类别值是否存在 | element.classList.contains('active'); |
classList.replace() |
用新的类值替换现有的类值 | element.classList.replace('old', 'new'); |
classList.remove() |
删除课程价值 | element.classList.remove('active'); |
我们将创建另一个HTML文件来处理类方法,包含两个元素和几个类。
<!DOCTYPE html>
<html lang="en">
<style>
body {
max-width: 600px;
margin: 0 auto;
font-family: sans-serif;
}
.active {
border: 2px solid blue;
}
.warning {
border: 2px solid red;
}
.hidden {
display: none;
}
div {
border: 2px dashed lightgray;
padding: 15px;
margin: 5px;
}
</style>
<body>
<div>Div 1</div>
<div class="active">Div 2</div>
</body>
</html>
当您将classes.html
文件打开到Web浏览器时,您应该会看到类似于以下内容的渲染:
引入className
属性是为了防止与JavaScript和其他访问DOM的语言中的class
关键字发生冲突。 您可以使用className
将值直接分配给类。
// Select the first div
const div = document.querySelector('div');
// Assign the warning class to the first div
div.className = 'warning';
我们已将classes.html
的CSS值中定义的warning
类分配给第一个div
。 您将收到以下输出:
请注意,如果元素上已有任何类,则会覆盖它们。 您可以使用className
属性添加多个空格分隔的类,也可以不使用赋值运算符来获取该元素上的类的值。
另一种修改类的方法是通过classList
属性,它带有一些有用的方法。 这些方法与jQuery addClass
, removeClass
和toggleClass
方法类似。
// Select the second div by class name
const activeDiv = document.querySelector('.active');
activeDiv.classList.add('hidden'); // Add the hidden class
activeDiv.classList.remove('hidden'); // Remove the hidden class
activeDiv.classList.toggle('hidden'); // Switch between hidden true and false
activeDiv.classList.replace('active', 'warning'); // Replace active class with warning class
执行上述方法后,您的网页将如下所示:
与className
示例不同,使用classList.add()
会将新类添加到现有类的列表中。 您还可以将多个类添加为逗号分隔的字符串。 也可以使用setAttribute
来修改元素的类。
修改样式
style属性表示HTML元素上的内联样式。 通常,样式将通过样式表应用于元素,就像我们在本文前面所做的那样,但有时我们必须直接添加或编辑内联样式。
我们将举一个简短的例子来演示JavaScript的编辑风格。 下面是一个带有div
的新HTML文件,其中有一些内联样式用于显示正方形。
<!DOCTYPE html>
<html lang="en">
<body>
<div style="height: 100px;
width: 100px;
border: 2px solid black;">Div</div>
</body>
</html>
当在网络浏览器中打开时, styles.html
将如下所示:
编辑样式的一个选项是setAttribute()
。
// Select div
const div = document.querySelector('div');
// Apply style to div
div.setAttribute('style', 'text-align: center');
但是,这将从元素中移除所有现有的内联样式。 由于这可能不是预期的效果,因此最好直接使用style
属性
div.style.height = '100px';
div.style.width = '100px';
div.style.border = '2px solid black';
CSS属性用kebab-case编写,小写字母用短划线分隔。 请注意,kebab-case CSS属性不能用于JavaScript样式属性。 相反,它们将被它们的camelCase等价物取代,即当第一个单词是小写字母时,所有后续单词都被大写。 换句话说,而不是text-align
我们将使用textAlign
作为JavaScript样式属性。
// Make div into a circle and vertically center the text
div.style.borderRadius = '50%';
div.style.display = 'flex';
div.style.justifyContent = 'center';
div.style.alignItems = 'center';
完成上述样式修改后,您最终呈现的styles.html
将显示一个圆圈:
如果将许多文体变化应用于元素,最好的方法是将样式应用于类并添加新类。 但是,在某些情况下,修改内联样式属性将是必要的或更直接的。
结论
HTML元素通常会以属性的形式为其分配其他信息。 属性可能由名称/值对组成,并且一些最常见的属性是class
和style
。
在本教程中,我们学习了如何使用普通JavaScript访问,修改和删除DOM中HTML元素的属性。 我们还学习了如何添加,移除,切换和替换元素上的CSS类,以及如何编辑内联CSS样式。 有关其他阅读,请查看Mozilla开发者网络上关于属性的文档。