愛在花開的季節 发表于 2024-6-8 23:28:47

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

前言

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


[*]项目地点:https://github.com/bradtraversy/50projects50days
Day 1 expanding-cards

效果预览
https://img-blog.csdnimg.cn/direct/3bd1e6412c61475b80de7f9f3fbb3750.png
核心代码:
<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

效果预览
https://img-blog.csdnimg.cn/direct/d33744be253d4258a82ad5db38daa9ca.png
核心代码:
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

效果预览
https://img-blog.csdnimg.cn/direct/414e8469bd1e4cb89ac4db179b121b2c.png
核心代码:
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/remove
[*]mouseenter 是鼠标移入变乱,mouseleave 是鼠标移出变乱
Day9 Sound Board

效果预览 (打开音频设备)
https://img-blog.csdnimg.cn/direct/105886dc700c4f9eb5c99ead4aaf4567.png
核心代码:
    <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

效果预览
https://img-blog.csdnimg.cn/direct/ba28e5ce1f5b44a5887048adc561b874.png
核心代码:
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 fetch
[*]Promise形式的链式调用 fetch then

Day11 Event Keycodes

https://img-blog.csdnimg.cn/direct/dd78b7faa6cb4b3dab5f7ba895926e6c.png


[*]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

演示地点
https://img-blog.csdnimg.cn/direct/c0088f0e2bf84ebcb73b19340966ccdd.png
跟 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中的伪类的本领。
https://img-blog.csdnimg.cn/direct/1f7fdea6be61470d9e7be539e27c5ecc.png
.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覆盖的知识
https://img-blog.csdnimg.cn/direct/8310ada815e8464db7daaab74c866260.png
.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元素就会被激活
https://img-blog.csdnimg.cn/direct/ccb95c8622464df9ab0e6f97ce76a1be.png

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【前端】夯实基础 css/html/js 50个练手项目(一连更新)