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

文章目录
    • 前言
    • [Day 1 expanding-cards](#Day 1 expanding-cards)
    • [Day 2 progress-steps](#Day 2 progress-steps)
    • [Day 7 Split Landing Page](#Day 7 Split Landing Page)
    • [Day9 Sound Board](#Day9 Sound Board)
    • [Day10 Dad Jokes](#Day10 Dad Jokes)
    • [Day11 Event Keycodes](#Day11 Event Keycodes)
    • [Day12 FAQ collapse](#Day12 FAQ collapse)
    • [Day46 Quiz App](#Day46 Quiz App)
      • [重点 label 标签的 for 属性](#重点 label 标签的 for 属性)

前言

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

Day 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/remove
  • mouseenter 是鼠标移入事件,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 fetch
    • Promise形式的链式调用 fetch then

Day11 Event Keycodes

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

    const insert = document.getElementById('insert')

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

    insert.innerHTML = `
    {event.key === ' ' ? 'Space' : event.key} event.key {event.keyCode} event.keyCode
    ${event.code} event.code ` })

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

复制代码
<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: '075';
  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: '075';
  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

    Question text

    • Question
      Submit
  • label for

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

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

相关推荐
每天吃饭的羊4 分钟前
next中的server comonent中如何共享session
服务器·前端·javascript
阿珊和她的猫5 分钟前
全局过滤器与局部过滤器: Vue中的文本格式化工具
前端·javascript·vue.js
木子李一11 分钟前
Vue 实现 Hls、Flv 协议视频播放
前端·vue.js·音视频
我爱吃朱肉37 分钟前
基于 HTML5 Canvas 实现图片旋转与下载功能
前端·html·html5
野猪佩奇0071 小时前
Git 使用的全流程以及SourceTree工具的使用操作和忽略文件的配置
开发语言·前端·git·sourcetree
WDeLiang2 小时前
Flutter 布局
前端·flutter·dart
pound1272 小时前
第十章.XML
xml·java·前端·javascript
11054654013 小时前
1、PLC控制面板 - /自动化与控制组件/plc-control-panel
运维·前端·javascript·自动化
前端极客探险家3 小时前
Vue 2.0 详解全教程(含 Axios 封装 + 路由守卫 + 实战进阶)
前端·javascript·vue.js
打小就很皮...3 小时前
浏览器存储 Cookie,Local Storage和Session Storage
前端·缓存·浏览器