【前端】夯实基础 css/html/js 50个练手项目(持续更新)

Ch.yang 2024-06-30 13:33:13 阅读 72

文章目录

前言Day 1 expanding-cardsDay 2 progress-stepsDay 7 Split Landing PageDay9 Sound BoardDay10 Dad JokesDay11 Event KeycodesDay12 FAQ collapse重点1:classList.toggle('active')重点2:css 伪类选择器重点3:css 的覆盖

Day46 Quiz App重点 label 标签的 for 属性

前言

发现一个没有用前端框架的练手项目,很适合我这种纯后端开发夯实基础,内含50个mini project,学习一下,做做笔记。

项目地址:https://github.com/bradtraversy/50projects50days

Day 1 expanding-cards

效果预览

Day1

核心代码:

<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

Day11 Event Keycodes

在这里插入图片描述

keyCode 是一个属性,这个项目可以当个字典用。原文演示地址

const insert = document.getElementById('insert')

window.addEventListener('keydown', (event) => {

insert.innerHTML = `

<div class="key">

${ event.key === ' ' ? 'Space' : event.key}

<small>event.key</small>

</div>

<div class="key">

${ event.keyCode}

<small>event.keyCode</small>

</div>

<div class="key">

${ event.code}

<small>event.code</small>

</div>

`

})

其中一个应用场景是禁止回车提交表单。

<form method="post">

<input type="text" name="username" id="username" onKeyPress="return EnterStop(event);"/>

<input type="button" value="提交" id="submint"/>

</form>

function EnterStop(e){

if(e.keyCode == 13){

return false;

}

}

Day12 FAQ collapse

演示地址

在这里插入图片描述

跟 day 1 一样,使用了 active 的思路,并且在js层面用 dom 查找父元素进行样式操作

<body>

<h1>Frequently Asked Questions</h1>

<div class="faq-container">

<div class="faq active">

<h3 class="faq-title">

Why shouldn't we trust atoms?

</h3>

<p class="faq-text">

They make up everything

</p>

<button class="faq-toggle">

<i class="fas fa-chevron-down"></i>

<i class="fas fa-times"></i>

</button>

</div>

</div>

<script src="script.js"></script>

</body>

重点1:classList.toggle(‘active’)

toggle 函数的能力:本例中,如果元素有 active 属性,那么就删除 ative。如果没有则追加。做到了一种类似开关的效果。

const toggles = document.querySelectorAll('.faq-toggle')

toggles.forEach(toggle => {

toggle.addEventListener('click', () => {

toggle.parentNode.classList.toggle('active')

})

})

重点2:css 伪类选择器

类选择器被激活后,包裹住div,用了一个css中的伪类的技巧。

在这里插入图片描述

.faq.active::before,

.faq.active::after {

content: '\f075';

font-family: 'Font Awesome 5 Free';

color: #2ecc71;

font-size: 7rem;

position: absolute;

opacity: 0.2;

top: 20px;

left: 20px;

z-index: 0;

}

重点3:css 的覆盖

这个图是拿css来画出来的,可以观察代码实现,利用了css覆盖的知识

在这里插入图片描述

.faq.active::before,

.faq.active::after {

content: '\f075';

font-family: 'Font Awesome 5 Free';

color: #2ecc71;

font-size: 7rem;

position: absolute;

opacity: 0.2;

top: 20px;

left: 20px;

z-index: 0;

}

// 覆盖样式,形成蓝色的图形

.faq.active::before {

color: #3498db;

top: -10px;

left: -30px;

transform: rotateY(180deg);

}

Day46 Quiz App

演示地址

重点 label 标签的 for 属性

html

<body>

<div class="quiz-container" id="quiz">

<div class="quiz-header">

<h2 id="question">Question text</h2>

<ul>

<li>

<input type="radio" name="answer" id="a" class="answer">

<!-- label 标签的文字与input绑定 -->

<label for="a" id="a_text">Question</label>

</li>

<!-- 忽略剩下3个选项 -->

</ul>

</div>

<button id="submit">Submit</button>

</div>

<script src="script.js"></script>

</body>

label for

当点击label标签内的文本后,就会触发绑定的表单元素。

上面的场景是点击问题的文字,input元素就会被激活

在这里插入图片描述



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。