持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情
翻译自github专栏
Day 21
文档对象模式(DOM)
HTML文档的结构为JavaScript对象,每个HTML元素都有不同的属性,使得我们可以对其进行不同操作。可以使用JavaScript获取、创建、添加或删除HTML元素。下面的示例。用JavaScript选择HTML元素类似于选择使用CSS。要使用某个HTML元素,我们使用标签名称,ID,样式名或其他属性。
获取元素
我们可以使用JavaScript访问已经创建的单个元素或者多个元素。有不同的方法获取元素。下面的代码有四个h1元素。让我们看看访问h1元素的不同方法。
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document Object Model</title>
</head>
<body>
<h1 class='title' id='first-title'>First Title</h1>
<h1 class='title' id='second-title'>Second Title</h1>
<h1 class='title' id='third-title'>Third Title</h1>
<h1></h1>
</body>
</html>
通过标签获取元素
getElementsByTagName():接受一个string类型的标签名称作为参数,返回HTMLCollection对象。HTMLCollection是一html元素类似数组的对象,其中length属性可以获取HTMLCollection对象的大小,当获取到该对象后,我们一般都是通过index直接访问指定元素,或者通过循环,来获取指定的元素,他不支持array的所有API,所以我们用正常的for i循环不用forEach方法
// syntax
document.getElementsByTagName('tagname')
const allTitles = document.getElementsByTagName('h1')
console.log(allTitles) //HTMLCollections
console.log(allTitles.length) // 4
for (let i = 0; i < allTitles.length; i++) {
console.log(allTitles[i]) // prints each elements in the HTMLCollection
}
通过classname样式名称获取元素
getElementsByClassName() 同样返回HTMLCollection对象. 和上面方法一致
//syntax
document.getElementsByClassName('classname')
const allTitles = document.getElementsByClassName('title')
console.log(allTitles) //HTMLCollections
console.log(allTitles.length) // 4
for (let i = 0; i < allTitles.length; i++) {
console.log(allTitles[i]) // prints each elements in the HTMLCollection
}
通过id获取元素
getElementsById() 返回单个HTML元素,正因为返回单个,所以要求id必须唯一。定义的时候id前面要加上#号
//syntax
document.getElementById('id')
let firstTitle = document.getElementById('first-title')
console.log(firstTitle) // <h1>First Title</h1>
通过querySelector 方法获取元素对象
document.querySelector 可以通过tag,id,classname获取元素对象
querySelector: 可以通过tag,id,class用来获取元素,返回第一个获取到的元素
let firstTitle = document.querySelector('h1') // 查找第一个存在的 tag为h1的 元素
let firstTitle = document.querySelector('#first-title') // 查找id为 first-title 的元素
let firstTitle = document.querySelector('.title') //通过class的名称获取元素
querySelectorAll: 顾名思义和上面不同的是,这个方法返回所有满足条件的元素,参数只能是标签名称tag, 或者class样式名称,返回一个nodeList的数组,支持array的方法。我们可以用for循环,或者forEach都可以遍历nodeList元素数组
const allTitles = document.querySelectorAll('h1') # 查找页面中所有的h1元素
console.log(allTitles.length) // 4
for (let i = 0; i < allTitles.length; i++) {
console.log(allTitles[i])
}
allTitles.forEach(title => console.log(title))
const allTitles = document.querySelectorAll('.title') // 所用使用到相同class的元素都会返回
添加属性
在HTML的开始标记中添加了属性,该属性提供了元素的其他信息,常用的属性包括:id, class, src, style, href,disabled, title, alt,我们在第四个标题中添加id和classname属性
const titles = document.querySelectorAll('h1')
titles[3].className = 'title'
titles[3].id = 'fourth-title'
通过 setAttribute方法,添加属性
setAttribute() 方法可以设置任何html的属性. 接受两个参数,属性类型,和属性名称 ,同样利用该方法在第四个标题上添加class和id属性
const titles = document.querySelectorAll('h1')
titles[3].setAttribute('class', 'title')
titles[3].setAttribute('id', 'fourth-title')
不使用 setAttribute添加属性
我们可以使用普通对象设置方法来设置属性,但这种方式不能适用于所有元素。有些属性是DOM对象属性,可以直接设置。例如实例id和class。
//another way to setting an attribute
titles[3].className = 'title'
titles[3].id = 'fourth-title'
添加class 通过classList方法
classList.add方法可以用来给元素添加多个属性. 不会覆盖之前的属性,添加额外属性。
//另一个方法添加class,不会覆盖原来的class
titles[3].classList.add('title', 'header-title')
remove方法移除样式属性
和添加样式属性很像,我们通过classList.remove方法移除样式属性
titles[3].classList.remove('title', 'header-title')
添加文本到院上上
一段由开始标签、结束标签和文本内容共同构成的HTML代码块 可以通过属性textContent或*innerHTML添加文本内容。
通过textContent添加
textContent 属性用于添加文本节点
const titles = document.querySelectorAll('h1')
titles[3].textContent = 'Fourth Title'
通过innerHTML添加文本节点
很多人会对 textContent 和 innerHTMl 两个方法搞混淆,区别就是innerHTML可以添加文本,HTML元素作为子元素,甚至多个元素。而textContent只能添加文本
Text Content
我们给 textContent 属性赋值文本
const titles = document.querySelectorAll('h1')
titles[3].textContent = 'Fourth Title'
Inner HTML
当我们想要替换父元素的子内容或将其替换为全新的子内容时,我们使用innerHTML属性。接受的值是一个HTML元素字符串
<!DOCTYPE html>
<html lang="en">
<head>
<title>JavaScript for Everyone:DOM</title>
</head>
<body>
<div class="wrapper">
<h1>Asabeneh Yetayeh challenges in 2020</h1>
<h2>30DaysOfJavaScript Challenge</h2>
<ul></ul>
</div>
<script>
const lists = `
<li>30DaysOfPython Challenge Done</li>
<li>30DaysOfJavaScript Challenge Ongoing</li>
<li>30DaysOfReact Challenge Coming</li>
<li>30DaysOfFullStack Challenge Coming</li>
<li>30DaysOfDataAnalysis Challenge Coming</li>
<li>30DaysOfReactNative Challenge Coming</li>
<li>30DaysOfMachineLearning Challenge Coming</li>`
const ul = document.querySelector('ul')
ul.innerHTML = lists
</script>
</body>
</html>
innerHTML属性同样可以移除所有父类的子元素来替代removeChild()方法。我推荐下面使用的innerHTML属性。
<!DOCTYPE html>
<html lang="en">
<head>
<title>JavaScript for Everyone:DOM</title>
</head>
<body>
<div class="wrapper">
<h1>Asabeneh Yetayeh challenges in 2020</h1>
<h2>30DaysOfJavaScript Challenge</h2>
<ul>
<li>30DaysOfPython Challenge Done</li>
<li>30DaysOfJavaScript Challenge Ongoing</li>
<li>30DaysOfReact Challenge Coming</li>
<li>30DaysOfFullStack Challenge Coming</li>
<li>30DaysOfDataAnalysis Challenge Coming</li>
<li>30DaysOfReactNative Challenge Coming</li>
<li>30DaysOfMachineLearning Challenge Coming</li>
</ul>
</div>
<script>
const ul = document.querySelector('ul')
ul.innerHTML = ''
</script>
</body>
</html>
添加style样式
添加style样式的颜色值
为标题添加一些风格。如果元素有偶数索引,设置为绿色,否则给它设置为红色。
const titles = document.querySelectorAll('h1')
titles.forEach((title, i) => {
title.style.fontSize = '24px' // 所有title的字体大小都是24px
if (i % 2 === 0) {
title.style.color = 'green'
} else {
title.style.color = 'red'
}
})
添加BackgroundColor属性
如果元素为第偶数个,设置为绿色背景,否则设置为红色背景。
const titles = document.querySelectorAll('h1')
titles.forEach((title, i) => {
title.style.fontSize = '24px' //所有title的字体大小都是24px
if (i % 2 === 0) {
title.style.backgroundColor = 'green'
} else {
title.style.backgroundColor = 'red'
}
})
添加字体大小样式
如果元素为第偶数个,设置为20px大小,否则舌害为30px
Let us add some style to our titles. If the element has even index we give it 20px else 30px
const titles = document.querySelectorAll('h1')
titles.forEach((title, i) => {
title.style.fontSize = '24px' // all titles will have 24px font size
if (i % 2 === 0) {
title.style.fontSize = '20px'
} else {
title.style.fontSize = '30px'
}
})
练习
练习: Level 1
- 创建index.html文件,加入4个p元素,通过document.querySelector(tagname) 方法获取所有元素
- document.querySelector('#id') 方法通过设置id来获取每个元素
- 获取p元素数组nodeList 通过使用 document.querySelectorAll(tagname) 方法
- 循环nodeList数组获取每个p元素的文本节点
- 将第四个p元素的文本设置成为:Fourth Paragraph
- 使用不同的属性设置方法为所有p标签设置id和class属性
练习: Level 2
- 使用JavaScript更改每个段落的样式(例如颜色、背景、边框、字体大小、什么字体等)
- 循环遍历每个元素,第1和3个元素设置为绿色,第2和4个元素设置为红色
- 给每个标签设置文本, id 和 class
练习: Level 3
DOM: Mini project 1
开发以下应用程序,使用以下HTML元素作为开头。您将在starter文件夹中获得相同的代码。仅使用JavaScript实现所有样式和功能。
- year的颜色每秒变化一次
- date 和 time 背景每秒变化一次
- 设置这个项目背景为绿色
- 继续改变颜色为黄色
- 最后改为红色
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>JavaScript for Everyone:DOM</title>
</head>
<body>
<div class="wrapper">
<h1>Asabeneh Yetayeh challenges in 2020</h1>
<h2>30DaysOfJavaScript Challenge</h2>
<ul>
<li>30DaysOfPython Challenge Done</li>
<li>30DaysOfJavaScript Challenge Ongoing</li>
<li>30DaysOfReact Challenge Coming</li>
<li>30DaysOfFullStack Challenge Coming</li>
<li>30DaysOfDataAnalysis Challenge Coming</li>
<li>30DaysOfReactNative Challenge Coming</li>
<li>30DaysOfMachineLearning Challenge Coming</li>
</ul>
</div>
</body>
</html>