Exercises One
📺JavaScript DOM Exercises 01
🔗Codepen
- 高亮文本关键词⭐
1 | /* 假设选择长度大于8的词语作为关键词 */ |
为页面添加一个链接节点
1
2
3
4const link = document.createElement("a");
link.href = "https://forcemipsum.com/";
link.innerText = "This is a new link";
document.body.appendChild(link);将文本段落按句子分割成段⭐
1
2
3
4const p = document.querySelector('p');
p.innerHTML = p.innerText
.split('. ')
.join('.</p><p>') + '</p>';计算文本的单词数并标注在标题下方
1
2
3
4
5
6
7
8const p = document.querySelector('p');
const len = p.innerText
.split(' ')
.length;
const wordsCount = document.createElement('div');
wordsCount.innerText = `${len} words`;
document.body.insertBefore(wordsCount, p);文本指定内容替换
1
2
3
4
5/* 假设将文本中的问号和感叹号分别替换为不同的emoji */
const p = document.querySelector('p');
p.innerHTML = p.innerHTML
.replace(/\?/g, '🤔')
.replace(/\!/g, '😲');
Exercises Two
📺JavaScript DOM Exercises 02
🔗Codepen
在输入框前插入标签
1
2
3document.getElementById('username').insertAdjacentHTML('beforebegin', '<label for="username">Username:</label>');
document.getElementById('password').insertAdjacentHTML('beforebegin', '<label for="password">Password:</label>');
document.getElementById('confirmPassword').insertAdjacentHTML('beforebegin', '<label for="confirmPassword">Confirm Password:</label>');在输入框后添加验证提示信息⭐
1
2
3
4
5
6
7
8
9
10
11
12const checkInput = (event => {
const warning = Array.from(event.target.parentNode.querySelectorAll('span'));
if (event.target.value === '' && !warning.length) {
event.target.insertAdjacentHTML('afterend', '<span style="color:red">Please enter your information!</span>');
}
if (event.target.value !== '' && warning.length) {
warning.forEach(element => {element.remove()});
}
});
document.getElementById('username').addEventListener('blur', checkInput);
document.getElementById('password').addEventListener('blur', checkInput);
document.getElementById('confirmPassword').addEventListener('blur', checkInput);验证“密码”与“确认密码”的一致性
1
2
3
4
5
6/* 可能不是很正确,这里使用了 event.target.value !== '' 来避免和上一条提示信息同时出现 */
document.getElementById('confirmPassword').addEventListener('blur', event => {
if (event.target.value !== document.getElementById('password').value && event.target.value !== '') {
event.target.insertAdjacentHTML('afterend', '<span style="color:red">Passwords should match!</span>');
}
});仅当所有必填项都填写后按钮才可点击
1
2
3
4
5
6
7
8
9
10
11
12/* 不太正确,按钮的可点击性没有密码一致性的限制 */
const button = document.querySelector('button');
button.setAttribute('disabled', 'disabled');
document.getElementById('registrationForm').addEventListener('change', (event) => {
const filled = Array.from(document.querySelectorAll('input')).every(input => input.value);
if (filled) {
button.removeAttribute('disabled');
}
else {
button.setAttribute('disabled', 'disabled');
}
});修改/添加提交表单触发事件
1
2
3
4
5
6/* 原先我认为直接在按钮上添加监听事件即可的,但是表单会默认提交,这有时候并不是我们想要的,所以不如修改表单默认监听事件 */
const form = document.getElementById('registrationForm');
form.addEventListener('submit', (event) => {
event.preventDefault();
alert("OK");
});
Exercises Three
📺JavaScript DOM Exercises 03
🔗Codepen
添加条目
1
2
3
4
5
6
7// 方法一:
const newItem = document.createElement('li');
newItem.innerText = '24/7 Phone support';
document.querySelector('#pro-plan ul').appendChild(newItem);
// 方法二:
document.querySelector('#pro-plan ul').insertAdjacentHTML('beforeEnd', '<li>24/7 Phone support</li>');交换节点位置/布局⭐
1
2
3
4
5
6
7// 方法一:交换DOM节点,将导致重排
const basic = document.querySelector('#basic-plan');
const pro = document.querySelector('#pro-plan');
basic.parentNode.insertBefore(basic, pro);
// 方法二:反转布局,将导致重绘
document.querySelector('.card-deck').style['flex-direction'] = 'row-reverse';获取并重新计算页面中的数据
1
2
3
4const basicStorage = document.querySelector('#basic-plan .storage-amount');
const proStorage = document.querySelector('#pro-plan .storage-amount');
basicStorage.innerText = basicStorage.innerText * 1.5;
proStorage.innerText = proStorage.innerText * 1.25;设置单选按钮组,根据选项显示不同信息⭐⭐⭐
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40document.querySelector('.container').insertAdjacentHTML('afterBegin', `<label>
Monthly
<input type="radio" value="monthly" name="pricing" id="monthlyPricing" checked>
</label>
<label>
Annual
<input type="radio" value="annual" name="pricing" id="annualPricing">
</label>`);
const pricing = {
monthly: {
basic: '10 / month',
pro: '30 / month'
},
annual: {
basic: '100 / year',
pro: '300 / year'
}
};
const changePricing = (event) => {
const selection = event.target.value;
// 根据属性选择即可,不需要条件语句判断
document.querySelector('#basic-plan .pricing').innerText = pricing[selection].basic;
document.querySelector('#pro-plan .pricing').innerText = pricing[selection].pro;
/*
const basicPricing = document.querySelector('#basic-plan .pricing');
const proPricing = document.querySelector('#pro-plan .pricing');
if (selection === 'monthly') {
basicPricing.innerText = pricing.monthly.basic;
proPricing.innerText = pricing.monthly.pro;
}
else {
basicPricing.innerText = pricing.annual.basic;
proPricing.innerText = pricing.annual.pro;
}
*/
};
Array.from(document.querySelectorAll('input[type="radio"]'))
.forEach(radio => radio.addEventListener('change', changePricing));
Exercises Four
📺JavaScript DOM Exercises 04
🔗Codepen
合并段落
1
2
3const paragraphs = document.querySelectorAll('#hero p');
paragraphs[0].insertAdjacentHTML('beforeEnd', paragraphs[1].innerText);
paragraphs[1].remove();修改字体大小(需获取样式计算结果)⭐
1
2
3
4const menuItem = document.querySelector('.menu ul li');
const menuFontSize = parseInt(window.getComputedStyle(menuItem).getPropertyValue('font-size'));
Array.from(document.querySelectorAll('p')).forEach(p => p.style.fontSize = `${menuFontSize / 2}px`);
//document.querySelector('p').style['font-size'] = `${menuFontSize / 2}px`;修改导航栏条目顺序
1
2
3
4// 注意,如果使用 childNodes 的话需要排除 "#text" 节点
const aboutNode = document.querySelector('.menu ul li:nth-child(2)');
const servicesNode = document.querySelector('.menu ul li:nth-child(3)');
aboutNode.insertAdjacentElement('beforeBegin', servicesNode);添加鼠标悬停效果⭐⭐
1
2
3
4
5
6
7
8
9
10
11
12
13
14const hoverEffect = (event) => {
const element = event.target;
element.style['background-color'] = '#f2f2f2';
element.style['font-size'] = '20px';
};
const normalEffect = (event) => {
const element = event.target;
element.style['background-color'] = '#fff';
element.style['font-size'] = '16px';
};
Array.from(document.querySelectorAll('.menu ul li')).forEach(item => {
item.addEventListener('mouseover', hoverEffect);
item.addEventListener('mouseleave', normalEffect);
});
Exercises Five
📺JavaScript DOM Exercises 05
🔗Codepen
复制元素
1
2
3
4
5
6
7
8
9
10
11
12const card = document.querySelector('.jobs .job-card');
const card1 = card.cloneNode(true);
const card2 = card.cloneNode(true);
const card3 = card.cloneNode(true);
/* 注意,这里需逆序插入 */
card.insertAdjacentElement('afterEnd', card3);
card.insertAdjacentElement('afterEnd', card1);
card.insertAdjacentElement('afterEnd', card2);
// const board = document.querySelector('.jobs');
// board.appendChild(card1);
// board.appendChild(card2);
// board.appendChild(card3);修改指定DOM节点的子元素
1
2card1.querySelector('h3').innerText = "JavaScript Developer";
// card1.childNodes[1].innerText = "JavaScript Developer";根据搜索框输入过滤节点⭐⭐⭐⭐
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15document.querySelector('#search').addEventListener('keyup', (event) => {
const element = event.target;
const input = element.value;
const cards = Array.from(document.querySelectorAll('.job-card'));
cards.forEach((card) => {
const title = card.querySelector('h3').innerText;
// if (title == input) {
if (title.toLowerCase().includes(input.toLowerCase())) {
card.style.display = 'block';
}
else {
card.style.display = 'none';
}
});
});点击诸如”show all”的按钮,恢复过滤前的所有节点
1
2
3
4
5
6document.querySelector('#show-all').addEventListener('click', () => {
document.querySelector('#search').value = '';
Array.from(document.querySelectorAll('.job-card')).forEach((card) => {
card.style.display = 'block';
});
});
Exercises Six
📺JavaScript DOM Exercises 02
🔗Codepen
在已有表格上新增一行⭐⭐⭐
1
2
3
4
5
6
7const newRow = document.createElement('tr');
['6', 'Sean', 'Reyes', '@sreyes'].forEach(text => {
const newCol = document.createElement('td');
newCol.innerText = text;
newRow.appendChild(newCol);
});
document.querySelector('table').appendChild(newRow);修改列值为”XX”的行的信息
1
2
3
4
5Array.from(document.querySelectorAll('table tr')).slice(1).forEach(row => {
if (row.querySelector('td:nth-child(2)').innerText == 'Leona' && row.querySelector('td:nth-child(3)').innerText == 'Dixon') {
row.querySelector('td:nth-child(4)').innerText = '@dixonl';
}
});将指定的一行移到指定位置,并重新整理序号⭐
1
2
3
4
5
6const rosa = document.querySelector('table tr:nth-child(5)');
document.querySelector('table tr:nth-child(1)').insertAdjacentElement('afterEnd', rosa);
// rosa.parentNode.insertBefore(row, document.querySelector('table tr:nth-child(2)'));
Array.from(document.querySelectorAll('table tr td:nth-child(1)')).forEach((item, idx) => {
item.innerText = idx + 1;
});将指定的一列移到指定位置⭐
1
2
3
4
5
6
7
8
9
10
11
12Array.from(document.querySelectorAll('table tr')).forEach(row => {
const handleCol = row.querySelector('th:nth-child(4), td:nth-child(4)');
const indexCol = row.querySelector('th:nth-child(1), td:nth-child(1)');
indexCol.insertAdjacentElement('afterEnd', handleCol);
});
// const handleTh = document.querySelector('table tr th:nth-child(4)');
// document.querySelector('table tr th:nth-child(1)').insertAdjacentElement('afterEnd', handleTh);
// const handles = Array.from(document.querySelectorAll('table tr')).slice(1);
// handles.forEach(row => {
// const handle = row.querySelector('td:nth-child(4)');
// row.querySelector('td:nth-child(1)').insertAdjacentElement('afterEnd', handle);
// });为表格奇偶行添加不同样式
1
2
3
4
5Array.from(document.querySelectorAll('table tr')).forEach((row, index) => {
if (index % 2 === 0) {
row.style['background-color'] = '#f2f2f2';
}
});
Summary
- Do not forget to convert “selectorAll” into “array”.
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.