文章目录
前言Day 1 expanding-cardsDay 2 progress-stepsDay 7 Split Landing PageDay9 Sound BoardDay10 Dad Jokes
前言
发现一个没有用前端框架的练手项目,很适合我这种纯后端开发夯实基础,内含50个mini project,学习一下,做做笔记。
项目地址:https://github.com/bradtraversy/50projects50daysDay 1 expanding-cards
效果预览
核心代码:
<body> <div class="container"> <!--active 标识被点击的图片 --> <div class="panel active" > </div> <div class="panel" > </div> <div class="panel" > </div> <div class="panel" > </div> <div class="panel" > </div> </div> <script src="script.js"></script> </body>
// 为所有的 panel 注册点击事件panels.forEach(panel => { panel.addEventListener('click', () => { // 清空所有 active 样式 removeActiveClasses() // 激活被点击 panel 的 active样式 panel.classList.add('active') })})function removeActiveClasses() { panels.forEach(panel => { panel.classList.remove('active') })}
知识点总结:
响应式布局flex: 5;
操作 classList
可以动态修改节点的 class
Day 2 progress-steps
效果预览
核心代码:
function update() { // Day1 中的处理方式 circles.forEach((circle, idx) => { if(idx < currentActive) { circle.classList.add('active') } else { circle.classList.remove('active') } }) // 按钮的禁用控制 if(currentActive === 1) { prev.disabled = true } else if(currentActive === circles.length) { next.disabled = true } else { prev.disabled = false next.disabled = false }}
知识点总结:
Day1 中的样式控制通用的前进后退按钮禁用逻辑 当前节点为第一个节点:后退按钮禁用当前节点为最后一个节点:前进按钮禁用其他情况,都不禁用Day 7 Split Landing Page
效果预览
核心代码:
const left = document.querySelector('.left')const right = document.querySelector('.right')const container = document.querySelector('.container')left.addEventListener('mouseenter', () => container.classList.add('hover-left'))left.addEventListener('mouseleave', () => container.classList.remove('hover-left'))right.addEventListener('mouseenter', () => container.classList.add('hover-right'))right.addEventListener('mouseleave', () => container.classList.remove('hover-right'))
知识点总结:
两种样式的互斥交互,成对编写 classList.add/removemouseenter 是鼠标移入事件,mouseleave 是鼠标移出事件Day9 Sound Board
效果预览 (打开音频设备)
核心代码:
<audio id="applause" src="sounds/applause.mp3"></audio> <audio id="boo" src="sounds/boo.mp3"></audio> <audio id="gasp" src="sounds/gasp.mp3"></audio> <audio id="tada" src="sounds/tada.mp3"></audio> <audio id="victory" src="sounds/victory.mp3"></audio> <audio id="wrong" src="sounds/wrong.mp3"></audio><!-- 作为容器给js添加按钮 --> <div id="buttons"></div> <script src="script.js"></script>
const sounds = ['applause', 'boo', 'gasp', 'tada', 'victory', 'wrong']sounds.forEach(sound => { const btn = document.createElement('button') btn.classList.add('btn') btn.innerText = sound// 注册事件 点击按钮就停止所有音效后,播放当前选中的音乐 btn.addEventListener('click', () => { stopSongs() document.getElementById(sound).play() })// 加进h5渲染页面 document.getElementById('buttons').appendChild(btn)})function stopSongs() { sounds.forEach(sound => { const song = document.getElementById(sound) song.pause() song.currentTime = 0; })}
知识点总结:
html中声明一个 div 作为容器,提供js渲染audio元素.play()
播放audio元素.pause() audio元素.currentTime = 0
停止 Day10 Dad Jokes
效果预览
核心代码:
jokeBtn.addEventListener('click', generateJoke)generateJoke()async function generateJoke() { const config = { headers: { Accept: 'application/json', }, } const res = await fetch('https://icanhazdadjoke.com', config) const data = await res.json() jokeEl.innerHTML = data.joke}
第二种generateJoke的写法 function generateJoke() { const config = { headers: { Accept: 'application/json', }, } fetch('https://icanhazdadjoke.com', config) .then((res) => res.json()) .then((data) => { jokeEl.innerHTML = data.joke }) }
知识点总结:
使用js发起异步http请求的两种方式 async await fetchPromise形式的链式调用 fetch then