【前端】夯实基础 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元素就会被激活

相关推荐
幽兰的天空29 分钟前
介绍一下CSS中伪类和伪元素的概念
前端·css·html·html5
问道飞鱼33 分钟前
【云原生知识】Kubernets实践-前端服务如何访问后端服务
前端·nginx·云原生
张姐学编程1 小时前
【C++】vector
前端·c++·学习·html
liuweni1 小时前
Next.js 自动化测试教程:Jest实战与优化
开发语言·前端·javascript·经验分享·前端框架·node.js
m0_748241702 小时前
BUUCTF之web篇
前端
工控匠2 小时前
ASP.net mvc--ECharts图表框架
前端·javascript·echarts
m0_748254662 小时前
SpringMVC 请求参数接收
前端·javascript·算法
编织幻境的妖2 小时前
使用html和JavaScript实现一个简易的物业管理系统
前端·javascript·html
九亿少女无法触及的梦ى2 小时前
uni-app 访问公司内网接口跨域解决
前端·nginx·uni-app·vue
GISer_Jing2 小时前
前端面试题目——性能分析题目大全
前端·vue.js·面试