0%

expanding Cards

演示地址:https://50projects50days.com/projects/expanding-cards/

Progress Steps

演示效果链接:https://50projects50days.com/projects/progress-steps/

思路:

1626277741081

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
*************HTML***************
<div class="container">
<div class="progress-container">
<div class="progress" id="progress"></div>
<div class="circle" active>1</div>
<div class="circle">2</div>
<div class="circle">3</div>
<div class="circle">4</div>
</div>
<button class="btn" id="prev" disabled>Prev</button>
<button class="btn" id="next">Next</button>
</div>

*************CSS***********
:root {
--line-border-fill: #3498db;
--line-border-empty: #e0e0e0;
}

* {
box-sizing: border-box;
}
body {
background-color: #f6f7fb;
font-family: 'Muli', sans-serif;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin: 0;
}

.container {
text-align: center;
}

.progress-container {
display: flex;
justify-content: space-between;
position: relative;
margin-bottom: 30px;
max-width: 100%;
width: 350px;
}

.progress-container::before{
content:'';
background-color: var(--line-border-empty);
position: absolute;
top:50%;
left:0;
transform: translateY(-50%);
height: 4px;
width:100%;
z-index: -1;
}

.progress{
background-color: var(--line-border-fill);
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
height: 4px;
width:0%;
z-index: -1;
transition: 0.4s ease;
}

.circle{
background-color: #fff;
color:#999;
border-radius: 50%;
height: 30px;
width: 30px;
display: flex;
align-items: center;
justify-content: center;
border: 3px solid var(--line-border-empty);
transition: 0.4 ease;
}

.circle.active{
border-color:var(--line-border-fill);

}

.btn{
background-color: var(--line-border-fill);
color: #fff;
border:0;
border-radius: 6px;
cursor:pointer;
font-family: inherit;
padding: 8px 30px;
margin:5px;
font-size: 14px;
}

.btn:active{
transform: scale(0.98);
}

.btn:focus{
outline:0;
}
.btn:disabled{
background-color: var(--line-border-empty);
cursor: not-allowed;
}
}


***********JS***********
const progress = document.getElementById('progress')
const prev = document.getElementById('prev')
const next = document.getElementById('next')
const circles = document.querySelectorAll('.circle')

let currentActive = 1
next.addEventListener('click', () => {
currentActive++

if(currentActive > circles.length) {
currentActive = circles.length
}
update()
})

prev.addEventListener('click', () => {
currentActive--

if(currentActive < 1) {
currentActive = 1
}
update()
})

function update() {
circles.forEach((circle, idx) => {
if(idx < currentActive) {
circle.classList.add('active')
} else {
circle.classList.remove('active')
}
})
const actives = document.querySelectorAll('.active')
progress.style.width = (actives.length - 1) / (circles.length - 1) * 100 + '%'
if(currentActive === 1) {
prev.disabled = true
} else if(currentActive === circles.length) {
next.disabled = true
} else {
prev.disabled = false
next.disabled = false
}
}

Hidden Search Widget

演示链接:https://50projects50days.com/projects/hidden-search-widget/

设计思路:

1.在使用图标的时候使用伪类,注意导入fontAwesome的链接,且用标签包起来

2、search类大类中包含input和btn,将btn和input的宽高设置成一样的,search设成相对定位,btn设成绝对定位,将btn的top和left都设置为0 ,这样btn和input就可以位于同一位置。

3、在写JS时不必将btn和input都设置active,只要在search设置acitve类就可以了。

  • ```
    HTML* CSS**
    *{
    box-sizing: border-box;
    }
    body {
    background-color:#678;
    font-family: ‘Roboto’, sans-serif;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    overflow: hidden;
    margin: 0;
    }.search {
    position: relative;
    height: 50px;
    background-color: rgb(194, 152, 97);
    }.search .input {
    background-color: #fff;
    border: 0;
    font-size: 18px;
    padding: 15px;
    height: 50px;
    width: 50px;
    transition: width 0.3s ease-in;
    }
    .btn{
    background-color: #fff;
    border:0;
    cursor: pointer;
    font-size: 24px;
    position: absolute;
    top:0;
    left: 0;
    height: 50px;
    width:50px;
    transition: transform 0.3s ease-in;
    
    } .btn:focus,
    .input:focus{
    outline: none;
    
    } .fa-search:before {
    content: "\f002";
    
    }.search.active .input{
    width: 200px
    }.search.active .btn{
    transform: translateX(200px);
    }JS*****
    const search= document.querySelector(“.search”);
    const btn = document.querySelector(‘.btn’);
    const input= document.querySelector(‘.input’);
    btn.addEventListener(‘click’, ()=>{
    search.classList.toggle(‘active’);
    input.focus();
    })
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11



    ## scroll Animation

    演示参考地址:https://50projects50days.com/projects/scroll-animation/

    设计思路:将未显示的盒子先向沿着X轴的两个方向隐藏起来,设置overflow-x: hidden; 奇数和偶数的box方向错开,添加scroll事件,按JS设置的条件显示box;

    JS:主要用到window.innerHeight/5*4, 即页面可视高度的80%,可以用getBoundingClientRect().top取到每一个Box距离页面顶端的高度,然后比较两者的值,当box的top值<页面高度的80%时,box应该要显示出来。

*HTML

Scroll to see the animation

Content

Content

Content

Content

Content

Content

Content

Content

**************CSS************* *{ box-sizing: border-box; } body{ font-family: 'Roboto', sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; margin: 0; overflow-x: hidden; } h1{ margin: 10px; }

.box{
background-color: rgb(173, 173, 238);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
width: 400px;
height: 200px;
margin: 10px;
box-shadow: 2px 4px 5px rgba(0,0,0, 0.3);
transform: translateX(200%);
transition: transform 0.4s ease;
}
.box:nth-of-type(even) {
transform: translateX(-200%);
}

.box.show {
transform: translateX(0);
}

.box h2 {
font-size: 45px;
}

JS
const boxes = document.querySelectorAll(‘.box’);
window.addEventListener(‘scroll’, checkBoxes);
checkBoxes();

function checkBoxes(){
const triggerBottom = window.innerHeight/5*4;
boxes.forEach(box=>{
let boxTop = box.getBoundingClientRect().top;
if(boxTop<triggerBottom){
box.classList.add(‘show’);
}else{
box.classList.remove(‘show’)
}
})
}

1
2
3
4
5
6
7
8
9
10
11

### Split Landing Page(拆分登录页)

演示参考地址: https://50projects50days.com/projects/split-landing-page/#

设计思路:

HTML和CSS : container 中包含split left 和split right 注意,这是多类选择器,包含两个类,两个split的宽度分辨设置成页面宽度的一半。然后对left 和right 进行定制设计,可添加伪类未图片设置透明背景色。

JS: 获取到lfet ,right和container,当鼠标发生mouseenter事件时,为container添加hover-right和hover-left类选择器,当鼠标发生mouseleave事件时,移除hover-right 和hover-left类选择器。

HTML

Playstation 5

Buy Now

XBox Seriese

Buy Now

CSS

  • {
    box-sizing: border-box;
    }

body {
font-family: ‘Roboto’, sans-serif;
height: 100vh;
overflow: hidden;
margin: 0;
}

h1 {
font-size: 3rem;
color: #fff;
position: absolute;
left: 50%;
top: 20%;
transform: translateX(-50%);
white-space: nowrap;
}

.btn {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
left: 50%;
top: 40%;
transform: translateX(-50%);
text-decoration: none;
color: #fff;
border: #fff solid 0.2rem;
font-size: 1rem;
font-weight: bold;
text-transform: uppercase;
width: 15rem;
padding: 1.2rem;
}

.split.left .btn:hover {
background-color: var(–left-btn-hover-color);
border-color: var(–left-btn-hover-color);
}

.split.right .btn:hover {
background-color: var(–right-btn-hover-color);
border-color: var(–right-btn-hover-color);
}

.container {
position: relative;
width: 100%;
height: 100%;
/* background: #333; */
}

.split {
position: absolute;
width: 50%;
height: 100%;
overflow: hidden;
}

.split.left{
left: 0;
background: url(‘https://50projects50days.com/projects/split-landing-page/ps.jpg');
background-repeat: no-repeat;
background-size: cover;
}

.split.left::before {
content: ‘’;
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(110, 122, 190, 0.5);
}

.split.right {
right: 0;
background: url(‘https://50projects50days.com/projects/split-landing-page/xbox.jpg');
background-repeat: no-repeat;
background-size: cover;
}

.split.right::before {
content: ‘’;
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(43, 43, 43, 0.6);
}

.split.right,
.split.left,
.split.right::before,
.split.left::before {
transition: all 1s ease-in;
}

.hover-left .left {
width: 75%;
}

.hover-left .right {
width: 25%;
}

.hover-right .right {
width: 75%;
}

.hover-right .left {
width: 25%;
}

@media (max-width: 800px) {
h1 {
font-size: 2rem;
top: 27%;
}

.btn {
padding: 1.1rem;
width: 12rem;
}
}

JS*****
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’));

1
2
3
4
5
6
7

### Faq Collapse

演示参考地址:https://50projects50days.com/projects/faq-collapse/

设计思路:container中包含5个fqa, 在第一个fqa上添加active类选择器,让其第一个显示出来,在JS中可选中所有的.fqa-toggle(button),用forEach遍历所有的.fqa-toggle,当发生点击事件(用toggle实现)的时候,为fqa添加或者移除active。

HTML

Frequently Asked Question

Why shouldn't we trust atoms?

They make up everything

<div class="faq">
  <h3 class="faq-title">
    Why do you call someone with nop body and no nose?
  </h3>
  <p class="faq-text">Nobody knows.</p>
  <button class="faq-toggle">
    <i class="fas fa-chevron-down"></i>
    <i class="fas fa-times"></i>
  </button>
</div>

<div class="faq">
  <h3 class="faq-title">
    What's the object-oriented way to become wealthy?
  </h3>
  <p class="faq-text">Inheritance.</p>
  <button class="faq-toggle">
    <i class="fas fa-chevron-down"></i>
    <i class="fas fa-times"></i>
  </button>
</div>

<div class="faq">
  <h3 class="faq-title">
 How many tickles does it take to tickle an octopus?
  </h3>
  <p class="faq-text">Ten-tickles.</p>
  <button class="faq-toggle">
    <i class="fas fa-chevron-down"></i>
    <i class="fas fa-times"></i>
  </button>
</div>

<div class="faq">
  <h3 class="faq-title">
    What is 1+1?
  </h3>
  <p class="faq-text">Depends on who are you asking.</p>
  <button class="faq-toggle">
    <i class="fas fa-chevron-down"></i>
    <i class="fas fa-times"></i>
  </button>
</div>

CSS*

  • {
    box-sizing: border-box;
    }

body {
font-family: ‘Muli’, sans-serif;
background-color: #f0f0f0;
}

h1 {
margin: 50px 0 30px;
text-align: center;
}

.faq-container {
max-width: 600px;
margin: 0 auto;
}

.faq {
background-color: transparent;
border: 1px solid #9fa4a8;
border-radius: 10px;
margin: 20px 0;
padding: 30px;
position: relative;
overflow: hidden;
transition: 0.3s ease;
}

.faq.active {
background-color: #fff;
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.2);
}

.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);
}

.faq-title {
margin: 0 35px 0 0;
}

.faq-text {
display: none;
margin: 30px 0 0;
}

.faq.active .faq-text {
display: block;
}

.faq-toggle {
background-color: transparent;
border: 0;
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
padding: 0;
position: absolute;
top: 30px;
right: 30px;
height: 30px;
width: 30px;
}

.faq-toggle:focus {
outline: 0;
}

.faq-toggle .fa-times {
display: none;
}

.faq.active .faq-toggle .fa-times {
color: #fff;
display: block;
}

.faq.active .faq-toggle .fa-chevron-down {
display: none;
}

.faq.active .faq-toggle {
background-color: #8bb8dd;
}

*JS
const toggles = document.querySelectorAll(‘.faq-toggle’);
toggles.forEach(toggle=>{
toggle.addEventListener(‘click’,()=>{
toggle.parentNode.classList.toggle(‘active’)
})
})

1
2
3
4
5
6
7

### Random Choice Picker

演示参考链接:https://50projects50days.com/projects/random-choice-picker/

设计思路:

***HTML

Enter all of the choices divided by a comma (',').
Press enter when you're done

*************CSS********* *{ box-sizing: border-box; }

body{
font-family: ‘Muli’, sans-serif;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 100vh;
text-align: center;
background-color: rgb(109, 108, 189);
overflow: hidden;
margin: 0;
}

.container{
width:500px;
}
h3{
color:aliceblue
}

textarea{
border: none;
display:block;
font-family: inherit;
width:100%;
height:100px;
padding: 10px;
margin: 0 0 20px;
}
.tag{
background-color: rgb(247, 167, 77);
border-radius: 50px;
color:#fff;
padding: 10px 20px;
margin: 0 5px 10px 0;
font-size: 14px;
display: inline-block;
}

.tag.highlight{
background-color: #273c75;
}

JS***
const tagsEl = document.getElementById(‘tags’);
const textarea = document.getElementById(‘textarea’);
textarea.focus();
textarea.addEventListener(‘keyup’, (e)=>{
createTags(e.target.value);
if(e.key===’Enter’){
setTimeout(() => {
e.target.value=’’;
}, 10);
randomSelect();
}
})

function createTags(input){
const tags = input.split(‘,’).filter(tag=>tag.trim() !==’’).map(tag=>tag.trim());
tagsEl.innerHTML=’’;
tags.forEach(tag=>{
const tagEl= document.createElement(‘span’);
tagEl.classList.add(‘tag’);
tagEl.innerText = tag;
tagsEl.appendChild(tagEl)

})
}
function randomSelect(){
setTimeout(() => {
const randomTag = pinkRandomTag();
highlightTag(randomTag);
}, 1000);
}

function pinkRandomTag(){
const tags = document.querySelectorAll(‘.tag’)
return tags[0]
}

function highlightTag(tag) {
tag.classList.add(‘highlight’)
}

1
2
3

### Animated Navigation

*HTML


***CSS
* {
box-sizing: border-box;
}
body {
background-color: #eafbff;
background-image:linear-gradient(
to bottom,
#eafbff 0%,
#eafbff 50%,
#52909f 50%,
#52909f 50%
);
font-family: ‘Muli’,sans-serif;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
margin:0;
}

nav{
  background-color: rgb(248, 247, 247);
  padding:20px;
  width:80px;
  display:flex;
  align-items: center;
  justify-content: center;
  border-radius: 3px;
  box-shadow:  0 2px 5px rgba(0,0,0,0.3);
  transition: width 0.6 linear;
  overflow-x: hidden;
}
nav.active {

width: 350px;
}

nav ul {
display: flex;
list-style-type: none;
padding: 0;
margin: 0;
width: 0;
transition: width 0.6s linear;
}

nav.active ul {
width: 100%;
}

nav ul li {
transform: rotateY(0deg);
opacity: 0;
transition: transform 0.6s linear, opacity 0.6s linear;

}

nav.active ul li {
opacity: 1;
transform: rotateY(360deg);
margin: 0 10px;
}

nav ul a {
position: relative;
color: #000;
text-decoration: none;

}

.icon {
background-color: #fff;
border: 0;
cursor: pointer;
padding: 0 10px;
position: relative;
height: 30px;
width: 30px;
}

.icon:focus {
outline: 0;
}

.icon .line {
background-color: #5290f9;
height: 2px;
width: 20px;
position: absolute;
top: 10px;
left: 5px;
transition: transform 0.6s linear;
}

.icon .line2 {
top: auto;
bottom: 10px;
}

nav.active .icon .line1 {
transform: rotate(135deg) translateX(3px) translateY(-2px) ;
}

nav.active .icon .line2 {
transform: rotate(-135deg) translateY(3px) translateX(2px) ;;
}

JS**
const toggle = document.getElementById(‘toggle’);
const nav= document.getElementById(‘nav’);
toggle.addEventListener(‘click’, ()=>nav.classList.toggle(‘active’))

1
2
3
4
5

### Incrementing Count

演示参考地址:https://50projects50days.com/projects/incrementing-counter/

HTML*****

Twitter Followers
Twitter Fllowers
FaceBook Fans

CSS*
*{
box-sizing: border-box;
}
body{
background-color:rgb(109, 64, 151) ;
display: flex;
font-family: ‘Roboto Mono’ ,sans-serif;
align-items: center;
justify-content: center;
height: 100vh;
margin:0;
overflow: auto;
color:aliceblue;
}
.count-container{
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
margin: 10px 40px;
padding: 10px 10px;

}

.count-container .counter{
font-size: 60px;
}
.count-container i{
color:rgb(252, 251, 253);
font-size: 90px;
}

.count-container span{
color:aliceblue;
font-size: 14px;
}

@media(max-width:589px){
body{
flex-direction: column;
}
}

JS****
const counters= document.querySelectorAll(‘.counter’);
counters.forEach(counter=>{
counter.innerHTML=”0”;
const updataCounter=()=>{
let targert = counter.dataset.targert;
let step = targert/200;
let c= +counter.innerHTML;
if(c<targert){
counter.innerHTML=${Math.ceil(c+step)}
setTimeout(updataCounter,1)
}
}
updataCounter();
})

1
2
3
4
5

### Drink Water

演示参考链接:https://50projects50days.com/projects/drink-water/

*HTML

Drink Water

Goal : 2 Liters

<small>Remained</small>

Select how many glasses of water that you have drank

250ml
250ml
250ml
250ml
250ml
250ml
250ml
250ml

CSS**
*{
box-sizing: border-box;
}

body{
background-color: rgb(49, 122, 182);
display: flex;
align-items: center;
justify-content: center;
margin-top: 40px;
flex-direction: column;
color:aliceblue
}

h1{
margin: 10px 0;
}
h3{
font-weight: 400px;
margin: 10px 0;
}
.cup{
height: 330px;
width: 150px;
background-color: #fff;
color:rgb(26, 130, 214);
border-radius: 0 0 40px 40px;
border:solid 4px #0c4aa7;
margin: 30px 0;
display: flex;
flex-direction: column;
overflow: hidden;
}
.remained{
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
text-align: center;
flex:1;
transition: 0.3s ease;
}

.cup .remained span{
font-size: 20px;
font-weight: bold;
}

.cup .remained small{
font-size: 12px;
}

.percentage{
background-color: aqua;
display: flex;
align-items: center;
justify-content: center;
font-size: 30px;
font-weight: bold;
height: 0;
transition: 0.3 ease-in;

}
.cups{
display: flex;
flex-wrap: wrap;
width: 280px;
align-items: center;
justify-content: center;
}
.cup.cup-small{
height: 95px;
width: 50px;
border-radius: 0 0 15px 15px;
background-color:rgba(255, 255, 255, 0.9) ;
cursor: pointer;
font-size: 14px;
align-items: center;
justify-content: center;
text-align: center;
margin:5px;
}

.cup.cup-small.full{
background-color: rgb(231, 152, 241);
color:#fff;
}

JS*****
const smallCups = document.querySelectorAll(‘.cup-small’);
const listers = document.getElementById(‘liters’);
const percentage= document.getElementById(‘percentage’);
const remained = document.getElementById(‘remained’);

updateBigCup();

smallCups.forEach((cup, index)=>{
cup.addEventListener(‘click’ ,()=>{
highlightCups(index)
})
})

function highlightCups(index){
smallCups.forEach((cup, index2)=>{
if(index2<=index){
cup.classList.add(‘full’);
}else{
cup.classList.remove(‘full’);
}
})
updateBigCup();
}

function updateBigCup(){
const totalCups = smallCups.length;
let fullCups = document .querySelectorAll(‘.cup-small.full’).length;
if(fullCups===0){
percentage.style.visibility=”hidden”;
percentage.style.height=0
}else{
percentage.style.visibility= ‘visible’;
percentage.style.height= ${fullCups/totalCups*330}px;
percentage.innerText=${fullCups/totalCups*100}%
}

if(fullCups===totalCups){
remained.style.visibility=”hidden”;
remained.style.height=0;
}else{
remained.style.visibility=”visible”;
listers.innerText=${2-fullCups*250/1000}L
}
}

1
2
3
4
5
6
7

### background Slide(背景幻灯片)

演示参考地址:https://50projects50days.com/projects/background-slider/

设计思路:初始化一个常量=0去记录幻灯片的索引,当点击左边按钮的时候,索引值-1,当点击右按钮的时候,索引常量+1,注意当这个记录常量值魏边界值<0时候,将其赋值为图片的长度-1,当记录常量值大于图片长度-1时,将其赋值为0,就可以实现幻灯片的循环播放。并将当前的幻灯片设置为背景图片,同时为对当前的幻灯片添加active类,使其显示出来。

******HTML

  <div
    class="slide"
    style="
      background-image: url('https://images.unsplash.com/photo-1495467033336-2effd8753d51?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2100&q=80');
    "
  ></div>

  <div
    class="slide"
    style="
      background-image: url('https://images.unsplash.com/photo-1522735338363-cc7313be0ae0?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2689&q=80');
    "
  ></div>

  <div
    class="slide"
    style="
      background-image: url('https://images.unsplash.com/photo-1559087867-ce4c91325525?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2100&q=80');
    "
  ></div>

**********CSS **************
*{
box-sizing: border-box;
}

body {
font-family: ‘Roboto’, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin: 0;
background-position: center center;
background-size: cover;
transition: 0.4s ease;
}

body::before {
content: ‘’;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background-color: rgba(0, 0, 0, 0.7);
z-index: -1;
}
.slider-container {
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.5);
height: 70vh;
width: 70vw;
position: relative;
overflow: hidden;
}

.slide {
opacity: 0;
height: 100vh;
width: 100vw;
background-position: center center;
background-size: cover;
position: absolute;
top: -15vh;
left: -15vw;
transition: 0.4s ease;
z-index: 1;
}

.slide.active {
opacity: 1;
}

.arrow {
position: fixed;
background-color: transparent;
color: #fff;
padding: 20px;
font-size: 30px;
border: 2px solid orange;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
}
.arrow:focus{
outline: 0;
}

.left-arrow{
left:calc(15vw - 68.5px);
}
.right-arrow{
right: calc(15vw - 65px);
}

JS
const body = document.body;
const leftBtn = document.getElementById(‘left’);
const rightBtn = document.getElementById(‘right’);
const slides = document.querySelectorAll(‘.slide’);

let slideActive=0;
rightBtn.addEventListener(‘click’, ()=>{
slideActive++;
if(slideActive>slides.length-1){
slideActive=0;
}
setBgToBody();
setActiveSlide();
})

leftBtn.addEventListener(‘click’, ()=>{
slideActive–;
if(slideActive<0){
slideActive=slides.length-1;
}
setBgToBody();
setActiveSlide();
})

setBgToBody();

function setBgToBody(){
body.style.backgroundImage = slides[slideActive].style.backgroundImage;
}

function setActiveSlide(){
slides.forEach(slide=>{
slide.classList.remove(‘active’);
})
slides[slideActive].classList.add(‘active’);
}

1
2
3
4
5

### Theme Clock

演示参考地址:https://50projects50days.com/projects/theme-clock/

HTML**

***************CSS***********
*{
box-sizing: border-box;
}

html{
transition: all 0.5s ease-in;
}
html.dark{
background-color: #111;
color:rgb(255, 251, 251);
}

body{
font-family: ‘Heebo’, sans-serif;
height: 100vh;
margin: 0;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}

.toggle{
cursor: pointer;
background-color: #000;
color:#fff;
border: 0;
border-radius: 4px;
padding: 8px 12px;
position: absolute;
top: 100px;
}

.toggle:focus{
outline: 0;
}
.clock-container{
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
border:2px solid #456;
}

.clock{
position: relative;
width:200px;
height:200px;
border: 2px red solid;
}

.needle{
background-color: #000;
position: absolute;
top:50%;
left:50%;
height: 65px;
width:3px;
transform-origin: bottom center;
transition: all 0.5s ease-in;
}

.needle.hour{
transform: translate(-50%,-100%) rotate(0deg);
background-color:#3c72e7;
}
.needle.minute{
transform: translate(-50%,-100%) rotate(0deg);
background-color:#151616;
}
.needle.second{
transform: translate(-50%, -100%) rotate(0deg);
height: 100px;
background-color: #e74c3c;
}
.center-point{
background-color: #e74c3c;
width:10px;
height: 10px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
}

.center-point::after{
content: ‘ ‘;
background-color: #000;
width: 5px;
height: 5px;
position:absolute;
top: 50%;
left: 50%;
/* 实现垂直居中 */
transform: translate(-50%, -50%);
border-radius: 50%;
}

time{
font-size: 60px;
}
.date{
color: #aaa;
font-size: 14px;
letter-spacing: 0.3px;
text-transform: uppercase;
}
.date .circle{
background-color: #000;
color: #fff;
border-radius: 50%;
height: 18px;
width: 18px;
display: inline-flex;
align-items: center;
line-height: 18px;
justify-content: center;
transition: all 0.5s ease-in;
font-size: 12px;
}

*******JS**********
const toggle = document.querySelector(‘.toggle’);
const hourEl = document.querySelector(‘.hour’);
const minuteEl = document.querySelector(‘.minute’);
const secondEl = document.querySelector(‘.second’);
const timeEl = document.querySelector(‘.time’);
const dateEl= document.querySelector(‘.date’);

const days = [“Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”];
const months = [“Jan”, “Feb”, “Mar”, “Apr”,”May”,”Jun”, “Jul”, “Aug”, “Sep”,”Oct”, “Nov”, “Dec”]

toggle.addEventListener(‘click’,(e)=>{
const html = document.querySelector(‘html’);
if(html.classList.contains(‘dark’)){
html.classList.remove(‘dark’);
e.target.innerHTML=’Dark mode’;
}else{
html.classList.add(‘dark’);
e.target.innerHTML=”Light mode”;
}
})

function setTime(){
const time = new Date();
const month = time.getMonth();
const day = time.getDay();//返回一星期中的某一天
const date = time.getDate();//返回一个月中的某一天
const hours = time.getHours();
const hoursForClock = hours >=13? hours%12 :hours;
const minutes = time.getMinutes();
const seconds = time.getSeconds();
const ampm = hours>=12 ? “PM” : “AM”;
hourEl.style.transform = translate(-50%, -100%) rotate(${hoursForClock /11*360}deg);
minuteEl.style.transform = translate(-50%, -100%) rotate(${minutes/59*360}deg);
secondEl.style.transform = translate(-50%, -100%) rotate(${seconds/59*360}deg);

timeEl.innerHTML = ${hoursForClock}:${minutes < 10 ? 0${minutes} : minutes} ${ampm}
dateEl.innerHTML = ${days[day]}, ${months[month]} <span class="circle">${date}</span>
}
setTime()
setInterval(setTime, 1000);

1
2
3
4
5

### Button Ripple Effect(按钮波纹效果)

演示参考地址:https://50projects50days.com/projects/button-ripple-effect/

HTML****

*****CSS
*{
box-sizing: border-box;

}
body{
background-color: black;
color:rgb(86, 151, 209);
font-family:’Roboto’, sans-serif;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
margin:0;
overflow: hidden;

}
.btn{
background-color: rgb(126, 37, 138);
padding :15px 20px;
color:azure;
border:0;
font-size: 14px;
text-transform: uppercase;
letter-spacing: 2px;
margin : 10px 0;
position: relative;
cursor: pointer;
overflow: hidden;
}
.btn:focus{
outline: 0;
}

button .circle{
position: absolute;
background-color: #fff;
width: 100px;
height: 100px;
border-radius: 50%;
transform: translate(-50%,-50%) scale(0);
animation: scale 0.5s ease-out;
}

@keyframes scale{
to{
transform: translate(-50%, -50%) scale(3);
opacity: 0;
}
}

JS***
let btns = document.querySelectorAll(“.btn”);

btns.forEach(btn=>{
btn.addEventListener(‘click’, function(e){

const x = e.clientX;
const y = e.clientY;

const buttonTop = e.target.offsetTop;
const buttonLeft = e.target.offsetLeft;

const xInside = x-buttonLeft;
const yInside = y-buttonTop;

const circle = document.createElement(‘span’);
circle.classList .add(‘circle’);
circle.style.left = xInside+”px”;
circle.style.top = yInside +”px”;
this.appendChild(circle);
// setTimeout(()=>circle.remove(), 500);
})
})

1
2
3
4
5

### Drag N Drop

演示参考地址:https://50projects50days.com/projects/drag-n-drop/

HTML*

*CSS
*{
box-sizing: border-box;
}
body{
background-color: rgb(111, 168, 214);
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
overflow: hidden;
}

.empty{
width: 150px;
height: 150px;
background-color: aliceblue;
border:2px solid black;
margin: 0 10px;
}

.fill{
background-image: url(‘https://source.unsplash.com/random/150x150');
height: 145px;
width: 145px;
cursor: pointer;
}

.hold{
border: solid 5px rgb(209, 33, 33);
}
.hovered{
background-color: #333;
border-color: white;
border-style: dashed;
}

@media(max-width:500px){
body{
flex-direction: column;
}
}

JS
const fill = document.querySelector(‘.fill’);
const empties = document.querySelectorAll(‘.empty’);

fill.addEventListener(‘dragstart’, dragStart);
fill.addEventListener(‘dragend’, dragEnd);

empties.forEach(empty=>{
empty.addEventListener(‘dragover’, dragOver);
empty.addEventListener(‘dragenter’, dragEnter);
empty.addEventListener(‘dragleave’, dragLeave);
empty.addEventListener(‘drop’, dragDrop);
})

function dragStart() {
console.log(this);
this.className += ‘ hold’;
setTimeout(() => this.className = ‘invisible’, 0);
}

function dragEnd() {
this.className = ‘fill’;
}

function dragOver(e) {
e.preventDefault()
}

function dragEnter(e) {
// e.preventDefault();
this.className += ‘ hovered’;
}

function dragLeave(){
this.className=”empty”;
}

function dragDrop(){
this.className = ‘empty’;
console.log(this);
this.append(fill);
}

1
2
3
4
5

### Drawing App

演示参考地址:https://50projects50days.com/projects/drawing-app/

HTML***

10

**CSS
*{
box-sizing: border-box;
}
body{
background-color: #f5f5f5;
font-family: ‘Roboto’ sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin:0;
}

canvas{
border: 2px solid steelblue;
}

.toolbox{
background-color: steelblue;
border: 1px solid slateblue;
display: flex;
width: 804px;
padding: 1rem;
}

.toolbox >*{
background-color: #fff;
border: none;
display: inline-block;
align-items: center;
justify-content: center;
font-size: 2rem;
height: 50px;
width: 50px;
margin: 0.25rem;
padding: 0.25rem;
cursor: pointer;
}

.toolbox >*:last-child{
margin-left: auto;
}

JS*
const canvas = document.getElementById(‘canvas’);
const increaseBtn = document.getElementById(‘increase’);
const decreaseBtn = document.getElementById(‘decrease’);
const sizeEl = document.getElementById(‘size’);
const colorEl = document.getElementById(‘color’);
const clearEl = document.getElementById(‘clear’);

const ctx = canvas.getContext(‘2d’);

let size = 10;
let isPressed = false;
colorEl.value = ‘black’;
let color = colorEl.value;
let x;
let y;

canvas.addEventListener(‘mousedown’, (e)=>{
isPressed=true;
x=e.offsetX;
y = e.offsetY;
})

canvas.addEventListener('mouseup', (e)=>{
  isPressed=false;
  x=undefined;
  y=undefined;
})

canvas.addEventListener('mousemove', (e)=>{
  if(isPressed){
    const x2 = e.offsetX;
    const y2 = e.offsetY;

    drawCircle(x2, y2);
    drawLine(x, y, x2,y2);
    x=x2;
    y=y2;

    }
})

function drawCircle(x, y){
  ctx.beginPath();
  ctx.arc(x, y, size, 0, Math.PI*2);
  ctx.fillStyle = color;
  ctx.fill();
}

function drawLine(x, y, x2, y2) {
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x2, y2);
ctx.strokeStyle = color;
ctx.lineWidth = size*2;
ctx.stroke();
}

increaseBtn.addEventListener(‘click’,()=>{
size+=5;
if(size>50){
size=50;
}
sizeEl.innerText = size;
})

decreaseBtn.addEventListener(‘click’, ()=>{
size-=5;
if(size<5){
size = 5;
}
sizeEl.innerText = size;
})

colorEl.addEventListener(‘change’, (e)=>{
color = e.target.value
})

clearEl.addEventListener(‘click’, ()=>{
ctx.clearRect(0,0, canvas.width, canvas.height);
})

1
2
3
4
5

### kinetic-loader(动力轮车)

演示参考地址:https://50projects50days.com/projects/kinetic-loader/

**HTML

css**
*{
box-sizing: border-box;
}

body{
background-color: #2c3e50;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin: 0;
}

.kinetic{
position: relative;
height: 80px;
width: 80px;
background-color: rgb(218, 186, 100);
}

.kinetic::after,
.kinetic::before{
content: ‘’;
position: absolute;
top: 0;
left: 0;
width:0;
height: 0;
border: 80px solid transparent;
border-bottom-color: #fff;
border-left-color: rgb(231, 123, 123);
animation: rotateA 2s linear infinite 0.5s;
}

.kinetic::before{
transform: rotate(90deg);
animation: rotateB 2s linear infinite ;
}

@keyframes rotateA {
0%,
25% {
transform: rotate(0deg);
}

50%,
75% {
transform: rotate(180deg);
}

100% {
transform: rotate(260deg);
}
}

@keyframes rotateB {
0%,
25% {
transform: rotate(90deg);
}

50%,
75% {
transform: rotate(270deg);
}

100% {
transform: rotate(450deg);
}
}

*JS
none

1
2
3

### content placehoder 内容占位符

HTML**

 

       

 
   

CSS***

  • {
    box-sizing: border-box;
    }

body {
background-color: #ecf0f1;
font-family: ‘Roboto’, sans-serif;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin: 0;
}

img {
max-width: 100%;
}

.card {
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
border-radius: 10px;
overflow: hidden;
width: 350px;
}

.card-header {
height: 200px;
}

.card-header img {
object-fit: cover;
height: 100%;
width: 100%;
}

.card-content {
background-color: #fff;
padding: 30px;
}

.card-title {
height: 20px;
margin: 0;
}

.card-excerpt {
color: #777;
margin: 10px 0 20px;
font-size: 14px;
}

.author {
display: flex;
}

.profile-img {
border-radius: 50%;
overflow: hidden;
height: 40px;
width: 40px;
}

.author-info {
display: flex;
flex-direction: column;
justify-content: space-around;
margin-left: 10px;
width: 100px;
}

.author-info small {
color: #aaa;
margin-top: 5px;
}

.animated-bg {
background-image: linear-gradient(
to right,
#f6f7f8 0%,
#edeef1 10%,
#d5dbe2 20%,
#dde2e7 100%
);
background-size: 200% 100%;
animation: bgPos 1s linear infinite;
}

.animated-bg-text {
border-radius: 50px;
display: inline-block;
margin: 0;
height: 10px;
width: 100%;
}

@keyframes bgPos {
0% {
background-position: 90% 0;
}
100% {
background-position: -150% 0;
}
}

**JS
const header = document.getElementById(‘header’)
const title = document.getElementById(‘title’)
const excerpt = document.getElementById(‘excerpt’)
const profile_img = document.getElementById(‘profile_img’)
const name = document.getElementById(‘name’)
const date = document.getElementById(‘date’)

const animated_bgs = document.querySelectorAll(‘.animated-bg’)
const animated_bg_texts = document.querySelectorAll(‘.animated-bg-text’)

setTimeout(getData, 2500)

function getData() {
header.innerHTML =

title.innerHTML = ‘Lorem ipsum dolor sit amet’
excerpt.innerHTML =
‘Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolore perferendis’
profile_img.innerHTML =

name.innerHTML = ‘John Doe’
date.innerHTML = ‘Oct 08, 2020’

animated_bgs.forEach((bg) => bg.classList.remove(‘animated-bg’))
animated_bg_texts.forEach((bg) => bg.classList.remove(‘animated-bg-text’))
}

1
2
3
4
5

### Sticky Navbar

演示参考链接:https://50projects50days.com/projects/sticky-navbar/

**HTML

Welcome To My Website

Lorem ipsum, dolor sit amet consectetur adipisicing elit. Maiores, consequuntur?

Content One

Lorem, ipsum dolor sit amet consectetur adipisicing elit. Ratione dolorem voluptates eveniet tempora ut cupiditate magnam, sapiente, hic quo in ipsum iste soluta eaque perferendis nihil recusandae dolore officia aperiam corporis similique. Facilis quos tempore labore totam! Consectetur molestiae iusto ducimus error reiciendis aspernatur dolor, modi dolorem sit architecto, voluptate magni sunt unde est quas? Voluptates a dolorum voluptatum quo perferendis aut sit. Aspernatur libero laboriosam ab eligendi omnis delectus earum labore, placeat officiis sint illum rem voluptas ipsum repellendus iste eius recusandae quae excepturi facere, iure rerum sequi? Illum velit delectus dicta et iste dolorum obcaecati minus odio eligendi!

Content Two

Lorem ipsum dolor sit amet consectetur, adipisicing elit. Pariatur provident nostrum possimus inventore nisi laboriosam consequatur modi nulla eos, commodi, omnis distinctio! Maxime distinctio impedit provident, voluptates illo odio nostrum minima beatae similique a sint sapiente voluptatum atque optio illum est! Tenetur tempora doloremque quae iste aperiam hic cumque repellat?

**CSS
*{
box-sizing: border-box;
margin: 0;
padding: 0;
}

body{
font-family: ‘Open Sans’ ,sans-serif;
color:#222;
padding-bottom: 50px;
}

.container{
max-width: 1200px;
margin: 0 auto;
}

.nav{
background-color: #222;
position: fixed;
top:0;
left:0;
right: 0;

transition: all 0.3s ease-in-out;
}

.nav .container {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 0;
transition: all 0.3s ease-in-out;
}

.nav ul{
display: flex;
justify-content: center;
list-style-type: none;
align-items: center;
}

.nav a{
color:#fff;
text-decoration: none;
padding: 7px 15px;
transition: all 0.3s ease-in-out;
}

.nav.active{
background-color: #fff;
box-shadow: 0 2px 10px rgba(0,0,0,0.3);
}

.nav.active a{
color:#000;
}

.nav.active .container {
padding:1px 0;
height: 70px;
}

.nav a.current,
.nav a:hover{
color: #c0392b;
font-weight: bold;
}

.hero{
background-image: url(‘https://images.pexels.com/photos/450035/pexels-photo-450035.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260');
background-repeat: no-repeat;
background-size: cover;
background-position: bottom center;
height: 100vh;
color:#fff;
display:flex;
align-items: center;
justify-content: center;
text-align: center;
position: relative;
margin-bottom: 20px;
z-index: -1;
}

.hero::before{
content: ‘’;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
z-index: -2;
}

.hero h1{
font-size: 46px;
margin: -20px 0 20px;
}

.hero p{
font-size: 20px;
letter-spacing: 1px;
}

.content h2,
.content h3{
font-size: 150%;
margin: 20px 20px;
}

.content p{
color: #555;
line-height: 30px;
letter-spacing: 1.2px;
padding-left: 20px;;
}

*JS
const nav = document.querySelector(‘.nav’)
window.addEventListener(‘scroll’, fixNav)

function fixNav() {
if(window.scrollY >300) {
nav.classList.add(‘active’)
} else {
nav.classList.remove(‘active’)
}
}

1
2
3
4
5

### Double Vertical Slider

演示参考地址: https://50projects50days.com/projects/double-vertical-slider/

***HTML

Flying eagle

in the sunset

<div style="background-color: #2A86BA">
  <h1>Nature flower</h1>
  <p>all in pink</p>
</div>

<div style="background-color: #252E33">
  <h1>Bluuue Sky</h1>
  <p> with it's mountains</p>
</div>

<div style="background-color: #FFB866">
  <h1>Lonely castle</h1>
  <p>in the wilderness</p>
</div>
    <button class="up-button">
      <i class=" iconfont icon-xiajiantou"></i>
    </button>
</div>

*CSS
*{
box-sizing: border-box;
margin: 0;
padding: 0;
}

body{
font-family: ‘Open Sans’, sans-serif;
height: 100vh;
}

.slider-container{
position: relative;
color:white;
width:100vw;
height: 100vh;
overflow: hidden;

}

.left{
position: absolute;
width:35%;
height:100%;
top:0;
left: 0;
transition: transform 0.5s ease-in-out;
}
.left div{
height: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.left h1{
margin-top: -30px;
margin-bottom: 10px;
}

.right{
position: absolute;
top:0;
left:35%;
height:100%;
width: 65%;
transition: transform 0.5s ease-in-out;
}
.right div{
width: 100%;
height: 100%;
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
}

button{
background-color: #fff;
position: absolute;
top:50%;
left: 35%;
padding: 10px 10px;
font-size: 18px;
border: none;
cursor: pointer;
z-index: 100;
}

.up-button{
transform: translateY(-100%);
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}

.down-button{
transform: translateX(-100%);
border-bottom-left-radius: 5px;
border-top-left-radius: 5px;
}

JS
const sliderContainer = document.querySelector(“.slider-container”);
const leftBtn = document.querySelector(‘.up-button’);
const rightBtn = document.querySelector(‘.down-button’);
const sliderRight = document.querySelector(‘.right’);
const sliderLeft = document.querySelector(‘.left’);
const slidersLength = sliderRight.querySelectorAll(‘div’).length;

let sliderActiveIndex=0;
sliderRight.style.top = ${-(slidersLength - 1) * 100}vh;

leftBtn.addEventListener(‘click’, ()=>changeSlide(‘up’));
rightBtn.addEventListener(‘click’, ()=>changeSlide(‘down’));

const changeSlide=(direnction)=>{
const sliderHeight = sliderContainer.clientHeight;
if(direnction===’up’){
sliderActiveIndex++;
if(sliderActiveIndex>slidersLength-1){
sliderActiveIndex=0;
}
}else if(direnction===”down”){
sliderActiveIndex–;
if(sliderActiveIndex<0){
sliderActiveIndex=slidersLength-1;
}

}

sliderRight.style.transform = translateY(${sliderActiveIndex*sliderHeight}px);
sliderLeft.style.transform = translateY(-${sliderActiveIndex*sliderHeight}px);

}

1
2
3
4
5

### toast notification

演示参考地址:https://50projects50days.com/projects/toast-notification/

HTML**

****CSS8
*{
box-sizing: border-box;
margin: 0;
padding: 0;
}

body{
  background-color: rgb(150, 50, 243);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
  margin: 0;
  position: relative;
}

button{
padding: 15px 7px;
border-radius: 6px;
border: 0ch;
color:rgb(76, 15, 145);
text-align: center;
font-weight: bold;
cursor: pointer;
}

button:focus{
outline: none;
}

button:focus{
transform: scale(0.98);
}

#toasts{
position: fixed;
bottom: 10px;
right: 10px;
display: flex;
flex-direction: column;
align-items: flex-end;
background-color: rgb(209, 69, 13);
}

.toast{
background-color: #fff;
border-radius: 5px;
padding: 1rem 2rem;
margin:0.5rem;
}
.toast.info{
color:rebeccapurple;
}

.toast.success{
color: green;
}

.toast.error{
color: red;
}

JS
const button = document.querySelector(‘button’);
const toasts = document.getElementById(‘toasts’);

const message = [‘Message One’, ‘Message Two’ ,’Message three’, ‘Message Four’];
const types = [‘info’, ‘success’, ‘error’];

button.addEventListener(‘click’, ()=>createNotification())

function createNotification(type=null, message=null){
const notif = document.createElement(‘div’);
notif.classList.add(‘toast’);
notif.classList.add(type ? type : getRandomType());
notif.innerText =message ? message: getRandomMessage();
toasts.appendChild(notif);

setTimeout(() => {
notif.remove();
}, 3000);
}

function getRandomType(){
return types[Math.floor(Math.random()*types.length)];
}

function getRandomMessage(){
return message[Math.floor(Math.random()*message.length)]
}

1
2
3

### GitHub Profile

**HTML

CSS*******
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}

body{
background-color: rgba(37, 22, 19, 0.795);
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height:100vh;
margin: 0;
overflow: hidden;

}

input{
padding: 15px 10px;
width: 700px;
border-radius: 7px;
border: none;
background-color: rgb(95, 28, 121);
margin-bottom: 20px;
box-shadow: 0 5px 10px rgba(154, 160, 185, 0.05),
0 15px 40px rgba(0, 0, 0, 0.1);
color:white
}
input::placeholder{
color:aliceblue
}

input:focus{
outline: none;
}

.card{
max-width: 800px;
background-color: #4c2885;
border-radius: 20px;
box-shadow: 0 5px 10px rgba(154, 160, 185, 0.05),
0 15px 40px rgba(0, 0, 0, 0.1);
margin: 0.5rem 0rem;
padding: 3rem;
display: flex;
}

.avatar{
border-radius: 50%;
border: 10px solid #2a2a72;
height: 150px;
width: 150px;
}

.user-info{
color:#eee;
margin-left: 2rem;
}

.user-info p{
border-bottom: 15px;
}
.user-info h2{
margin-bottom: 5px;
}

.user-info ul{
list-style-type: none;
display: flex;
justify-content: space-between;
padding: 0;
max-width: 400px;
margin-bottom: 5px;
}

.user-info ul li{
display: flex;
align-items: center;
}

.user-info ul li strong{
font-size: 0.9rem;
margin-left: 0.5rem;
}

.repo{
text-decoration: none;
color: #fff;
background-color: #212a72;
font-size: 0.7rem;
padding: 0.25rem 0.5rem;
margin-right: 0.5rem;
margin-bottom: 0.5rem;
display: inline-block;
}

@media(max-width:500px){
.card{
flex-direction:column;
align-items: center;
}
form{
max-width:400px;
}
}
}

***JS
const APIURL= ‘http://api.github.com/users/'

const main = document.getElementById(‘main’);
const form = document.querySelector(‘.form’);
const search = document.getElementById(‘search’);

async function getUser(username) {
try{
const { data } =await axios(APIURL + username);
createUserCard(data);
getRepos(username);
}catch(error){
if(error.response.status ===404){
createErrorCard(‘查询不到相关信息’);
}
}
}
async function getRepos(username){
try {
const {data} =await axios(APIURL + username+’/repos?sort=created’);
addReposToCard(data);

} catch (error) {
createErrorCard(‘查询错误’);
}
}

function createUserCard(user){
const cardHtml = <div class="card"> <div > <img src="${user.avatar_url}" alt="${user.name}" class="avatar"> </div> <div class="user-info"> <h1>${user.name}</h1> <p> ${user.bio}</p> <ul> <il>${user.followers}<strong>Followers</strong></li> <il>${user.followering}<strong>Followering</strong></li> <il>${user.public_repos}<strong>Repos</strong></li> </ul> <div id="repos"></div> </div> </div>
main.innerHTML = cardHtml;
}

function createErrorCard(msg){
const cardHtml = <div class="card"> <h1>${msg}</h1> </div>
main.innerHTML = cardHtml;
}

function addReposToCard(repos){
const reposEl = document.getElementById(‘repos’);
repos.slice(0, 5).forEach(repo=>{
let repoEl =document.createElement(‘a’);
repoEl.classList.add(‘repo’);
repoEl.href =repo.html_url;
repoEl.innerHTML = repo.name;
repoEl.target = “_blank”;
reposEl.appendChild(repoEl);
})
}

form.addEventListener(‘submit’, (e)=>{
e.preventDefault();
const user = search.value;
if(user){
getUser(user);
search.value=””;
}

})

1
2
3

### double Click

HTML

Double click on the image to it

You liked it 0 times

CSS*
*{
box-sizing: border-box;
margin: 0;
padding: 0;
}

body {
font-family: ‘Oswald’, sans-serif;
text-align: center;
overflow: hidden;
margin: 0;
}

h3 {
margin-bottom: 0;
text-align: center;
}

small {
display: block;
margin-bottom: 20px;
text-align: center;
}

.fa-heart {
color: red;
}

.loveMe {
height: 440px;
width: 300px;
background: url(‘https://images.unsplash.com/photo-1504215680853-026ed2a45def?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=334&q=80')
no-repeat center center/cover;
margin: auto;
cursor: pointer;
max-width: 100%;
position: relative;
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
}

.loveMe .fa-heart {
position: absolute;
animation: grow 0.6s linear;
transform: translate(-50%, -50%) scale(0);
}

@keyframes grow {
to {
transform: translate(-50%, -50%) scale(10);
opacity: 0;
}
}

*JS
let times = document.getElementById(‘times’);
const div = document.querySelector(‘.loveMe’);
let clickTimes = 0;
let resetTime = 0;
div.addEventListener(‘click’,(e)=>{
clickTimes++;
resetTime++
times.innerText = clickTimes;
if(resetTime==2){
resetTime=0;
// const heart = document.createElement(‘i’)
// heart.classList.add(‘fas’)
// heart.classList.add(‘fa-heart’)
// div.appendChild(heart);
createHeart(e);
}

})

const createHeart = (e) => {
const heart = document.createElement(‘i’)
heart.classList.add(‘fas’)
heart.classList.add(‘fa-heart’)
console.log(e);

const x = e.clientX
const y = e.clientY

const leftOffset = e.target.offsetLeft
const topOffset = e.target.offsetTop

const xInside = x - leftOffset
const yInside = y - topOffset

heart.style.top = `${yInside}px`
heart.style.left = `${xInside}px`

div.appendChild(heart);
setTimeout(() => heart.remove(), 1000)

}

1
2
3

### Password Generator

*HTML

Password Generator

***CSSS
*{
box-sizing: border-box;
margin: 0;
padding: 0;
}

body{
background-color: rgb(127, 127, 226);
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin:0;
flex-direction: column;
color: white;
}

.container{
background-color: blueviolet;
padding: 10px 20px;
box-shadow: 0px 2px 10px rgba(255, 255, 255, 0.2);
width: 400px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
h1{
font-size: 24px;
}
.result-container{
display: flex;
justify-content: space-between;
width:100%;
background-color: black;
padding: 7px 7px;

}

.result-container span{
display: inline-block;
width: 75%;

padding: 7px;
}

.result-container button{
height: 40px;
width:40px;
background-color: rgb(151, 63, 235);
font-size: 25px;
color:aliceblue;
margin-right: 0;
border: none;
}
.result-container button i{
font-size: 23px;
}

.setting{
width:100%;

}
.setting .setting{
display: flex;
margin-top: 15px;
justify-content: space-between;
width: 100%;
}
.setting label{
margin-right: 98px;
}
.setting input{
margin-right: 0px;
}

.btn{
border: none;
cursor: pointer;
}
.btn:focus{
outline: none;

}
.btn-large{
background-color:rgb(74, 6, 105);
padding: 10px 20px;
margin: 15px 0;
width: 100%;
color: white
}

JS**

const resultEl = document.getElementById(‘result’);
const clipboardEl = document.getElementById(‘clipboard’)
const lengthEl = document.getElementById(‘length’);
const uppercaseEl = document.getElementById(‘uppercase’);
const lowercaseEl = document.getElementById(‘lowercase’);
const numbersEl = document.getElementById(‘numbers’);
const symbolsEl = document.getElementById(‘symbols’);
const generateEl = document.getElementById(‘generate’);

//点击复制按钮复制生成的密码
clipboardEl.addEventListener(‘click’ ,()=>{
const textarea = document.createElement(‘textarea’);
const password = resultEl.innerHTML;
if(!password) return;
textarea.value= password;
document.body.appendChild(textarea);
textarea.select();
document.execCommand(‘copy’);
textarea.remove();
alert(‘已成功复制代码’);

})

//点击生成密码按钮生成密码

generateEl.addEventListener(‘click’,()=>{
const length = +lengthEl.value;
const hasLower = lowercaseEl.chcked;
const hasUpper = uppercaseEl.chcked;
const hasNumber = numbersEl.chcked;
const hasSymbol = symbolsEl.checked;
resultEl.innerText = generatePassword(hasLower,hasUpper,hasNumber,hasSymbol, length)
console.log(resultEl.value);
})

//存储所有的随机函数
const randomFunc = {
lower: getRandomLower,
upper: getRandomUpper,
number: getRandomNumber,
symbol: getRandomSymbol
}

//生成代码函数
function generatePassword(lower, upper, number, symbol, length){
let generatedPassword =’’;
let typesCount = lower+ upper+ number + symbol;
if(typesCount==0) return ‘’;
const typesArr=[{lower}, {upper}, {number},{ symbol}];

for(let i= 0; i<length; i++){
typesArr.forEach(type=>{
const funcName = Object.keys(type)[0]
generatedPassword += randomFuncfuncName
})
}
const finalPassword = generatedPassword.slice(0, length)
return finalPassword;
}

function getRandomLower() {
return String.fromCharCode(Math.floor(Math.random() * 26) + 97)
}

function getRandomUpper() {
return String.fromCharCode(Math.floor(Math.random() * 26) + 65)
}

function getRandomNumber() {
return String.fromCharCode(Math.floor(Math.random() * 10) + 48)
}

function getRandomSymbol() {
const symbols = ‘!@#$%^&*(){}[]=<>/,.’
return symbols[Math.floor(Math.random() * symbols.length)]
}

1
2
3

### Good Cheap Fast

HTML**

How do you want your project to be?

Good
Cheap
Fast

*****CSS
body{
font-family: ‘Robot’, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin: 0;
}

.toggle-container {
display: flex;
align-items: center;
margin: 10px 0;
width: 200px;
}

.toggle-container .label{
width: 80px;
height :40px;
position: relative;
border-radius: 50px;
background-color:rgb(192, 192, 186);
margin: 0 10px;
}

.toggle-container .label .ball{
position: absolute;
top: 3px;
left: 3px;
width: 34px;
height:34px;
background-color: aliceblue;
border-radius: 50%;
animation: slideOff 0.3s linear forwards;
}
.toggle-container .toggle{
visibility: hidden;
}

.toggle:checked+.label{
background-color: rgb(171, 113, 226);
}

.toggle:checked +.label .ball{
animation: slideOn 0.3s linear forwards;
}
@keyframes slideOff{

0%{
  transform: translateX(40px) scale(1);
}
50%{
  transform: translateX(20px) scale(1.2);
}

100%{
  transform: translateX(0px) scale(1);
}

}

@keyframes slideOn{
0%{
transform: translateX(0px) scale(1);
}

50%{
transform: translateX(20px) scale(1.2);
}

100%{
transform: translateX(40px) scale(1);
}
}

*JS
const toggles = document.querySelectorAll(‘.toggle’);
const good = document.getElementById(‘good’);
const cheap = document.getElementById(‘cheap’);
const fast = document.getElementById(‘fast’);

toggles.forEach(toggle=>toggle.addEventListener(‘click’,(e)=>{
if(good.checked&&cheap.checked&&fast.checked){
if(e.target==cheap){
good.checked=false;
}

if(e.target===fast){
  cheap.checked=false;
}

if(e.target===good){
  fast.checked=false;
}

}
}))

1
2
3
4
5

### Notes App

参考演示地址: https://50projects50days.com/projects/notes-app/

HTML

CSS*
*{
box-sizing: border-box;
padding: 0;
margin: 0;
}

body{
background-color: rgb(86, 194, 236);
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
margin: 60px 40px;

}

.add{
position: fixed;
top: 15px;
right:20px;
padding: 6px 15px;
background-color: rgb(231, 119, 74);
border:none;
color:aliceblue;
cursor: pointer;
}

.add:active{
transform: scale(0.98);
}

.note{
background-color: #fff;
box-shadow: 0 0 10px 4px rgba(0, 0, 0, 0.1);
margin: 30px 20px;
height: 400px;
width: 300px;

}

.tools{
background-color: rgba(236, 124, 33, 0.849);
padding: 10px 12px;
border: none;
display: flex;
justify-content: flex-end;

}

.tools button{

border: none;
background-color: transparent;
cursor: pointer;
margin-left: 0.5rem;
}

.tools button i{
color:white;
cursor: pointer;
font-size: 24px;
}

.note textarea{
border:none;
outline: none;
font-family: inherit;
height: 400px;
width:100%;
padding: 20px;
}

.main{
padding: 20px;
width:100%;
word-wrap: break-word;

}

.hidden{
display: none;
}

JS
const addBtn = document.querySelector(‘.add’);

//localstage会将之前存储的字段显示出来,要不然打开页面以前的数据就没法显示
const notes =JSON.parse(localStorage.getItem(‘notes’));
if(notes){
notes.forEach(note=>addNewNote(note));
}

addBtn.addEventListener(‘click’, ()=>addNewNote())

function addNewNote(text=””) {
const note = document.createElement(‘div’);
note.classList.add(‘note’);
document.body.appendChild(note)
note.innerHTML = <div class="tools"> <button class="edit"> <i class="iconfont icon-bianji"></i></button> <button class="delete" > <i class="iconfont icon-shanchu"></i></button> </div> <div class="main ${text? "" : "hidden"}"></div> <textarea class ="${text ? "hidden" : ""}"></textarea>
const editBtn = note.querySelector(“.edit”);
const deleteBtn = note.querySelector(“.delete”);
const main = note.querySelector(‘.main’);
const textAarea = note.querySelector(‘textarea’);
//把缓存里的notesl里的值传入到textAarea和main中。
textAarea.value = text;
main.innerHTML= text;

editBtn.addEventListener(‘click’, ()=>{
main.classList.toggle(‘hidden’);
textAarea.classList.toggle(‘hidden’);
})

deleteBtn.addEventListener(‘click’, ()=>{
note.remove();
updateLS();
})

textAarea.addEventListener(‘input’, (e)=>{

console.log(e.target);
main.innerHTML=e.target.value;
updateLS();
})

}
//更新localStorage函数

function updateLS(){
const textnotes= document.querySelectorAll(‘textarea’);
let notes = [];
textnotes.forEach(textnote=>{
notes.push(textnote.value);
localStorage.setItem(‘notes’, JSON.stringify(notes));
})

}

1
2
3
4
5

### Animated Countdown

演示参考地址:https://50projects50days.com/projects/animated-countdown/

HTML**

3 2 1 0

GET READY

GO

CSS*
body{
font-family: ‘Roboto’ ,sans-serif;
margin: 0;
height: 100vh;
overflow: hidden;
}

h4{
font-size: 20px;
margin: 5px;
text-transform: uppercase;
}

.counter{
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}

.counter.hide{
transform: translate(-50%,-50%) scale(0);
animation: hide 0.2s ease-out;
}

@keyframes hide{
0%{
transform: translate(-50%, -50%) scale(1);
}

100%{
transform: translate(-50%, -50%) scale(0);
}
}

.nums{
color:#3498db;
font-size: 50px;
position: relative;
overflow: hidden;
width: 250px;
height: 50px;

}

.nums span{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(120deg);
transform-origin: bottom center;
}

.nums span.in{
transform: translate(-50%, -50%) rotate(0deg);
animation: goIn 0.5s ease-in-out;
}

.nums span.out{
animation: goOut 0.5s ease-in-out;
}

@keyframes goIn{
0%{
transform: translate(-50%, -50%) rotate(120deg);
}

30%{
transform:translate(-50%, -50%) rotate(-20deg);
}
60%{
transform:translate(-50%, -50%) rotate(10deg);
}
100%{
transform:translate(-50%, -50%) rotate(10deg);
}
}

@keyframes goOut{
0%{
transform: translate(-50%, -50%) rotate(0deg);
}

60%{
transform: translate(-50%, -50%) rotate(20deg);
}

100%{
transform: translate(-50%, -50%) rotate(-120deg);
}
}

.final{
position:fixed;
top: 50%;
left: 50%;
/* 先隐藏起来 */
transform: translate(-50%, -50%) scale(0);
text-align: center;
}

.final.show{
transform: translate(-50%,-50%) scale(1);
animation: show 0.2s ease-out;
}

@keyframes show{

0%{
transform: translate(-50%, -50%) scale(0);
}

30%{
transform: translate(-50%, -50%) scale(1.4);
}

100%{
transform: translate(-50%, -50%) scale(1);
}

}

JS****
const counter = document.querySelector(‘.counter’);
const nums = document.querySelectorAll(‘.nums span’);
const final = document.querySelector(‘.final’);
console.log(final);
const replay = document.getElementById(‘replay’);

runAnimation();

function runAnimation(){
nums.forEach((num,index)=>{
const lastindex = nums.length-1;
num.addEventListener(‘animationend’ ,(e)=>{
if(e.animationName==’goIn’ && index!==lastindex){

    num.classList.remove('in');
    num.classList.add('out');
  }

 else if(e.animationName==='goOut' && num.nextElementSibling){
    num.nextElementSibling.classList.add('in')
  }else{
    counter.classList.add('hide');
    final.classList.add('show');
  }

})

})
}

replay.addEventListener(‘click’ ,()=>{
resetAnimation();
runAnimation();
})

function resetAnimation() {

final.classList.remove(‘show’);
counter.classList.remove(‘hide’);

nums.forEach((num)=>{
num.classList.value=’’;
})

nums[0].classList.add(‘in’);
}

1
2
3
4
5

### mobile Tab Navigation

演示参考地址:https://50projects50days.com/projects/mobile-tab-navigation/

**HTML

home work blog about

*CSS
body{
background-color: #B88ACB;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
font-family: sans-serif;
font-style: 16px;
color:rgb(150, 149, 149)

}

.phone{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border: 3px solid #fff;
border-radius: 15px;
height: 600px;
width: 400px;
overflow: hidden;
}

.phone .img{
position: relative;
height: 90%;
overflow: hidden;
width:400px
}

.img .content{
position: absolute;
top:0;
left: 0;
height: 100%;
width: 100%;
object-fit: cover;

opacity: 0;

transition: opacity 0.4s ease
}

.img .content.show{
opacity: 1;
}

nav{
width: 100%;
height: 10%;

}

nav ul{
list-style-type: none;
display: flex;
align-items: center;
justify-content: space-between;
text-align: center;
padding: 12px 10px ;
background-color: #fff;

}
nav ul li{
cursor: pointer;
}

nav ul li:hover{
color:#c580e2;
}
nav ul li.active{
color:#b963dd
}

*****JS
const imgs = document.querySelectorAll(‘.content’);
const lis = document.querySelectorAll(‘li’);

lis.forEach((li, index)=>{
li.addEventListener(‘click’, ()=>{
hideAllImages();
hideAllLis()

li.classList.add('active');
imgs[index].classList.add('show')

})
})

function hideAllImages(){
imgs.forEach(img=>{
img.classList.remove(‘show’);
})
}

function hideAllLis() {
lis.forEach(li=>{
li.classList.remove(‘active’);
})
}

1
2
3
4
5
6
7
8
9
10
11
12
13

### Password strength Backgrond

参考演示地址: https://50projects50days.com/projects/password-strength-background/

#### 该项目是用tailwindcss框架写的,用的时候要插入引用

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/1.8.11/tailwind.min.css"

integrity="sha512KO1h5ynYuqsFuEicc7DmOQc+S9m2xiCKYlC3zcZCSEw0RGDsxcMnppRaMZnb0DdzTDPaW22ID/gAGCZ9i+RT/w=="crossorigin="anonymous"

/>

*******HTML *********

Image Password Strength

Change the password to see the effect

<button class="bg-black text-white py-2 mt-4 inlne-block w-full  rounded" type="submit">Submit</button>

CSS*

body{
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 100vh;
overflow: hidden;
margin: 0;
}

.background{
background: url(‘https://images.unsplash.com/photo-1556745757-8d76bdb6984b')
no-repeat center/cover;
position: absolute;
top:-20px;
left:-20px;
right: -20px;
bottom: -20px;
z-index: -1;
filter: blur(20px);
}

JS*
const bgImg = document.querySelector(‘.background’);
const password = document.getElementById(‘password’);

password.addEventListener(‘input’ ,(e)=>{
const input = e.target.value
const length = input.length
const blurValue = 20 - length * 2
bgImg.style.filter = blur(${blurValue}px)

})

1
2
3
4
5

### 3D background Boxes

参考演示地址: https://50projects50days.com/projects/3d-background-boxes/

HTML

CSS*

body {
background-color: #fafafa;
font-family: ‘Roboto’, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
}

.magic{
background-color: #f9ca24;
color:#fff;
font-family: ‘Poppins’ , sans-serif;
border: 0;
border-radius: 3px;
font-size: 16px;
padding: 12px 12px;
cursor: pointer;
position: fixed;
top: 20px;
letter-spacing: 1px;
box-shadow: 0 3px rgba(249, 202,36, 0.5);
z-index: 100;
}

.magic:focus{
outline: none;
}

.magic:active{
box-shadow: none;
transform: translateY(2px);
}

.boxes{
display: flex;
flex-wrap: wrap;
justify-content: space-around;
height: 500px;
width: 500px;
position: relative;
transition: 0.4s ease;
}

.boxes.big{
width: 600px;
height: 600px
}

.boxes.big .box{
transform: rotateZ(360deg);

}

.box{
background-image: url(‘https://media.giphy.com/media/EZqwsBSPlvSda/giphy.gif');
position: relative;
background-size: 500px 500px;
background-repeat: no-repeat;
width: 125px;
height: 125px;
transition: 0.3s ease;

}

.box:before{
content: ‘’;
background-color: #f9ca24;
position: absolute;
bottom: -15px;
left: 8px;
height: 15px;
width: 100%;
transform: skewX(45deg);
}

.box::after{
content: ‘’;
background-color: #ebd281;
position: absolute;
top: 8px;
right: -15px;
width: 15px;
height: 100%;
transform: skewY(45deg);
}

***JS

const boxesContainer = document.getElementById(‘boxes’)
const btn = document.getElementById(‘btn’)

btn.addEventListener(‘click’, () => boxesContainer.classList.toggle(‘big’))

function createBoxes() {
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 4; j++) {
const box = document.createElement(‘div’)
box.classList.add(‘box’)
box.style.backgroundPosition = ${-j * 125}px ${-i * 125}px
boxesContainer.appendChild(box)
}
}
}

createBoxes()

1
2
3
4
5

### Verify Account Ui

演示参考链接: https://50projects50days.com/projects/verify-account-ui/

HTML*

Verify Your Account

We emailed you the six digit code to cool_guy@email.com Enter the code below to confirm your email address.

This is design only. We didn't actually send you an email as we don't have your email, right?

******CSS
body{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin: 0;
}

.container{
height: 100%;
width: 80%;
border-left:3px solid #000;
border-right:3px solid #000;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}

h1{
font-size: 40px;
font-weight: 600;
margin-top: 20px;
}

h4{
font-size: 20px;
max-width: 600px;
margin-top: 20px;
font-weight: 200;
}

.input-container{
display: flex;

align-items: center;
width: 100%;
margin-top: 50px;
justify-content: ;

}

.input{
border:1px solid rgb(211, 207, 207);
width:136px;
height: 160px;
line-height: 160px;
/* justify-content: space-between; */
text-align: center;
margin: 9px;
font-size: 75px;
border-radius: 7px;
-moz-appearance: textfield;
}

.input::-webkit-outer-spin-button,
.input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}

.input:valid{
border-color: #3498db;
box-shadow: 0 10px 10px -5px rgba(0,0,0,0.25);
}

.p{
max-width: 600px;
margin-top: 60px;
background-color: rgb(235, 215, 192);
border-radius: 10px;
padding: 13px 20px;
text-align: center;
line-height: 30px;
}

@media(max-width:900px){
.input-container{
flex-wrap: wrap;
}

@media(max-width:600px){
.input-container{
flex-wrap: wrap;
}

.input{
font-size: 60px;
height: 80px;
max-width: 70px;
}
}
}

JS******
const inputs = document.querySelectorAll(‘input’);
inputs[0].focus();
inputs.forEach((input ,index) => {
input.addEventListener(‘keydown’, (e)=>{
if(e.key>=0 && e.key<=9){
inputs[index].value =’’; //每次输入后将值置空,保证下次输入的时候不会保存原先输入的值。
setTimeout(() => {
if(index<inputs.length-1)
inputs[index+1].focus();
}, 10);
}
else if(e.key==’Backspace’){
setTimeout(() => {
inputs[index-1].focus();
}, 10);
}
})
});

1
2
3
4
5

### Live User Filter

演示参考地址:https://50projects50days.com/projects/live-user-filter/

**********HTML ***********

Live User Filter

Search by name and/or location
  • Loading....

***********CSS ************
body{
background-color: #f8f9fd;
font-family: ‘Roboto’ , sans-serif;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin-top: 10px;
margin-bottom: 10px;
}

.container{
border-radius: 5px;
box-shadow: 3px 3px 10px rgba(0,0,0, 0.2);
overflow: hidden;
width: 400px;
overflow-y: auto;

}

.title{
margin: 0;
font-size: 26px;
}

.subtitle{
display: inline-block;
margin: 5px 0 20px;
opacity: 0.8;
font-size: 16px;
}

.header{
background-color: #3e57db;
color:#fff;
padding: 30px 20px;
}

.header input{
background-color: rgba(0,0,0,0.3);
border: 0;
border-radius: 50px;
color: #fff;
font-size: 14px;
padding: 10px 15px;
width: 100%;
}

.header input:focus{
outline: none;
}

.user-list{
list-style-type: none;
background-color: #fff;
width: 100%;
max-height: 400px;
overflow-y: auto;
}

.user-list li{
display: flex;
padding: 10px 12px;
width: 100%;
}
.user-list:last-child{
padding-bottom: 20px;
background-color: transparent;
}

.user-list li img{
border-radius: 50%;
height: 90px;
width:90px;
object-fit: cover;
margin-left: 10px;
}

.user-list .user-info{
margin-left: 10px;
}

.user-list .user-info h4{
margin: 0 0 10px;
font-size: 20px;
font-weight: 600;
}

.user-list .user-info p{
font-size: 14px;
}

.user-list li:not(:last-of-type){
border-bottom: 1px solid #eee;
}

.user-list li.hide{
display: none;
}

***JS
const filter = document.getElementById(‘filter’);
const result = document.getElementById(‘result’);
const resultItem = [];

getData();
filter.addEventListener(‘input’ , (e)=>{filterData(e.target.value)});

async function getData(){
const res = await fetch(‘https://randomuser.me/api?results=50');
let {results} = await res.json();
console.log(results);
result.innerHTML=’’;

results.forEach(user => {
const li = document.createElement(‘li’);
li.innerHTML = <img src ="${user.picture.large}" alt="${user.name.first}"> <div class="user-info"> <h4>${user.name.first} ${user.name.last}</h4> <p> ${user.location.city}, ${user.location.country}</p> </div>
result.appendChild(li);
resultItem.push(li)
});

}

function filterData(searchValue) {
resultItem.forEach(item=>{
if(item.innerText.toLowerCase().includes(searchValue.toLowerCase())){
item.classList.remove(‘hide’);
}else{
item.classList.add(‘hide’);
}
})
}

1
2
3
4
5

### Feedback UI Design

演示参考地址: https://50projects50days.com/projects/feedback-ui-design/

***HTML

How satisfied are you with our customer support performance?

  • Unhappy

  • <li>
      <img src="https://image.flaticon.com/icons/svg/187/187136.svg">
      <p>Neutral</p>
    </li>
    
    <li>
      <img src="https://image.flaticon.com/icons/svg/187/187133.svg">
      <p>Satisfied</p>
    </li>
    

Thank You!

We'll use your feedback to improve our customer support

***CSS
body{
background-color: #FEF9F2;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
overflow: hidden;
position: relative;
}

.container1{
width: 600px;
height: 400px;
box-shadow: 0 10px 20px rgba(0,0,0, 0.3);
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: 10px 10px;
background-color: #fdfdfc;
position: absolute;
opacity: 1;
}

.container1 h1{
font-size: 22px;
max-width: 400px;
font-weight: 400;
}

.container1 ul{
list-style-type: none;
display: flex;
align-items: center;
justify-content: center;
padding-top: 15px;
}

.container1 li{
padding: 15px 12px;
margin: 0 5px;
cursor: pointer;

width: 150px;
height: 150px;

}

.container1 li img{
width:60px;
height: 60px;
margin-top: 10px;
}

.container1 li p{
margin-top: 15px;
color:#899
}

.container1 li:hover{
box-shadow: 0px 2px 5px rgba(20, 20, 20, 0.2);
}

.container1 li.active{
box-shadow: 0px 2px 5px rgba(20, 20, 20, 0.2);
}

button{
margin: 40px 0;
padding: 15px 10px;
width: 220px;
border-radius: 7px;
border: none;
background-color:#f3ba10 ;
color: #fdfdfc;
font-size: 24px;
cursor: pointer;
outline: none;
}

button:active{
transform: scale(0.98);
}

.container2{
width: 600px;
height: 300px;
box-shadow: 0 10px 20px rgba(0,0,0, 0.3);
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding: 10px 10px;
background-color: #fdfdfc;
z-index: -1;

}

.container2 i{
color: red;
font-size: 29px;
margin-top: 20px;
}

.container2 h3,p{
margin-top: 20px;
}
.container2 p{
max-width: 400px;
font-size: 18px;
}

****jS
let lis=document.querySelectorAll(‘li’);
let btn = document.getElementById(‘btn’);

const container1 = document.querySelector(‘.container1’)
const container2 = document.querySelector(‘.container2’);
const container2h3= document.querySelector(‘.container2 h3’);

lis.forEach(li => {
li.addEventListener(‘click’, (e)=>{
removeChangeLi();
li.classList.add(‘active’)
})
});

function removeChangeLi(){
lis.forEach(li=>{
li.classList.remove(‘active’);
})
}

btn.addEventListener(‘click’, (e)=>{show()})

function show(){
if(lis[0].classList.contains(‘active’)){
container1.remove();
container2h3.innerText=’Feedback:Unhappy’;
}
else if(lis[1].classList.contains(‘active’)){
container1.remove();
container2h3.innerText=’Feedback:Neutrual’;
}
else{
container1.remove();
container2h3.innerText=’Feedback:Satisfied’;
}
}

1
2
3
4
5
6
7
8
9
10

其他浏览器内与该功能类似的伪类

- ::-moz-range-thumb //火狐
- ::-ms-thumb //IE

### custom Range Slider

演示参考链接:https://50projects50days.com/projects/custom-range-slider/

HTML***

Custom Range Slider

****************CSS *************
body{
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
overflow: hidden;
background-image: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);

}

h2 {
position: absolute;
top: 10px;
}

.range-container {
position: relative;
}

input[type=’range’] {
width: 300px;
margin: 18px 0;
-webkit-appearance: none;
}

input[type=’range’]:focus {
outline: none;
}

input[type=’range’] + label {
background-color: #fff;
position: absolute;
top: -25px;
left: 110px;
width: 80px;
padding: 5px 0;
text-align: center;
border-radius: 4px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
}

input[type=’range’]::-webkit-slider-runnable-track {
background: purple;
border-radius: 4px;
width: 100%;
height: 10px;
cursor: pointer;
}

input[type=’range’]::-webkit-slider-thumb {
-webkit-appearance: none;
height: 24px;
width: 24px;
background: #fff;
border-radius: 50%;
border: 1px solid purple;
margin-top: -7px;
cursor: pointer;
}

*JS
const range = document.getElementById(‘range’)

range.addEventListener(‘input’, (e) => {
const value = +e.target.value
const label = e.target.nextElementSibling

const range_width = getComputedStyle(e.target).getPropertyValue('width')

const label_width = getComputedStyle(label).getPropertyValue('width');

//去掉’px‘这个单位
const num_width = +range_width.substring(0, range_width.length - 2)
const num_label_width = +label_width.substring(0, label_width.length - 2)

const max = +e.target.max

const min = +e.target.min

const left = value * (num_width / max) - num_label_width / 2 + scale(value, min, max, 10, -10)
// const left = 300/110*value-40+(y2-y1)/(x2-x1)*3;

label.style.left = `${left}px`
label.innerHTML = value
1
2
3
4
5

### quiz App

演示参考地址:https://50projects50days.com/projects/quiz-app/

**************HTML************

Question text

  •   <li>
        <input type="radio" name="answer" id="b" class="answer">
        <label for="b" id="b_text">Question</label>
      </li>
    
      <li>
        <input type="radio" name="answer" id="c" class="answer">
        <label for="c" id="c_text">Question</label>
      </li>
    
      <li>
        <input type="radio" name="answer" id="d" class="answer">
        <label for="d" id="d_text">Question</label>
      </li>
    </ul>
    <button id=submit>Submit</button>
    

*************CSS***********
body{
background-color: #EAEEF4;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin: 0;
}

.quiz-container{
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
background-color: #fff;
margin: 10px 0;
padding: 25px 40px;
width: 700px;
border-radius: 8px;

}

.header-container{

}
h2{
line-height: 45px;
text-align: center;
font-size: 34px;

}

.header-container ul{
list-style-type: none;

}
.header-container ul li{
font-size: 25px;
margin: 40px;
}

.header-container ul li input{
transform: scale(1.3);
color: #8E44AD

}

.header-container ul li label{
cursor: pointer;
padding-left: 10px;
}

button{
width:100%;
background-color: #8E44AD;
padding: 12px 12px;
border: none;
color: white;
font-size: 20px;
cursor: pointer;
outline: none;
margin-bottom: 10px;
}

button:focus {
outline: none;
background-color: #5e3370;
}
button:hover {
background-color: #732d91;
}

.reload-button{
margin: 30px 0;
}

**************JS*********************
const quizData=[
{
question: “Which language runs in a web browser?”,
a: “Java”,
b: “C”,
c: “Python”,
d: “JavaScript”,
correct: “d”,
},

{
    question: "What does CSS stand for?",
    a: "Central Style Sheets",
    b: "Cascading Style Sheets",
    c: "Cascading Simple Sheets",
    d: "Cars SUVs Sailboats",
    correct: "b",
},
{
    question: "What does HTML stand for?",
    a: "Hypertext Markup Language",
    b: "Hypertext Markdown Language",
    c: "Hyperloop Machine Language",
    d: "Helicopters Terminals Motorboats Lamborginis",
    correct: "a",
},
{
    question: "What year was JavaScript launched?",
    a: "1996",
    b: "1995",
    c: "1994",
    d: "none of the above",
    correct: "b",
},

]

const quiz = document.getElementById(‘quiz’);
const questionEl= document.getElementById(‘question’);
const answerEls = document.querySelectorAll(‘.answer’);
const a_text = document.getElementById(‘a_text’);

const b_text = document.getElementById(‘b_text’);
const c_text = document.getElementById(‘c_text’);
const d_text = document.getElementById(‘d_text’);
const submitBtn = document.getElementById(‘submit’);

let chengji = 0;
let currentQuizIndex = 0;

loadQuiz();

function loadQuiz(){
clearAnswerData();
questionEl.innerText = quizData[currentQuizIndex].question;
a_text.innerText = quizData[currentQuizIndex].a;
b_text.innerText = quizData[currentQuizIndex].b;
c_text.innerText = quizData[currentQuizIndex].c;
d_text.innerText = quizData[currentQuizIndex].d;
}

function clearAnswerData(){
answerEls.forEach(answerEl=>{
answerEl.checked = false;
})
}

function getAnswer(){
let answer;
answerEls.forEach(answerEl=>{
if(answerEl.checked===true){
answer = answerEl.id;
}
})
return answer;
}

submitBtn.addEventListener(‘click’ ,()=>{
let answer = getAnswer();
if(answer){
if(answer===quizData[currentQuizIndex].correct){
chengji++;
}
if(currentQuizIndex<quizData.length-1){
currentQuizIndex++;
loadQuiz();
}else{
quiz.innerHTML = <h2>You answered ${chengji}/${quizData.length} questions correctly</h2> <button onclick="location.reload()" class="reload-button">Reload</button>
}
}else{
alert(‘未选择答案’)
}
})

1
2
3
4
5

### Testimonial Box Switch

演示参考地址: https://50projects50days.com/projects/testimonial-box-switcher/

HTML*******

0%

CSS
body{
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
margin:20px auto;
}

.container{
background-color: #29788b;
border-radius: 9px;
padding: 40px;
display: flex;
justify-content: center;
align-items: center;
text-anchor: center;
flex-direction: column;
color:aliceblue;
position: relative;
}

.progress{
width:100%;
height: 7px;
background-color: rgb(91, 215, 236);
animation: grow 20s linear infinite;
transform-origin: left;
}

span{
position: absolute;
top: 20px;
right: 20px
}

@keyframes grow{
0%{
transform: scaleX(0);
}
}
p{
margin: 20px 0;
max-width: 700px;
line-height: 35px;
font-size: 20px;
}
p::before{

}

p::after{

}

.info{
display: flex;
justify-content: center;
align-items: center;
}

img{
width: 80px;
height: 80px;
object-fit: cover;
border-radius: 50%;
border: none;
}
.user-info{
margin-left: 15px;
text-align: center;
margin-top: 20px;

}

.user-info h3{
margin-bottom: -20px;
}

JS******
const pEl = document.querySelector(‘p’);
const imgEl = document.querySelector(‘img’);
const h3El = document.querySelector(‘h3’);
const pinfoEl = document.querySelector(‘.pinfo’);
const span = document.querySelector(‘span’)

const datas=[
{
name: ‘Miyah Myles’,
position: ‘Marketing’,
photo:
https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&s=707b9c33066bf8808c934c8ab394dff6',
text:
“I’ve worked with literally hundreds of HTML/CSS developers and I have to say the top spot goes to this guy. This guy is an amazing developer. He stresses on good, clean code and pays heed to the details. I love developers who respect each and every aspect of a throughly thought out design and do their best to put it in code. He goes over and beyond and transforms ART into PIXELS - without a glitch, every time.”,
},
{
name: ‘June Cha’,
position: ‘Software Engineer’,
photo: ‘https://randomuser.me/api/portraits/women/44.jpg',
text:
‘This guy is an amazing frontend developer that delivered the task exactly how we need it, do your self a favor and hire him, you will not be disappointed by the work delivered. He will go the extra mile to make sure that you are happy with your project. I will surely work again with him!’,
},
{
name: ‘Iida Niskanen’,
position: ‘Data Entry’,
photo: ‘https://randomuser.me/api/portraits/women/68.jpg',
text:
“This guy is a hard worker. Communication was also very good with him and he was very responsive all the time, something not easy to find in many freelancers. We’ll definitely repeat with him.”,
},
{
name: ‘Renee Sims’,
position: ‘Receptionist’,
photo: ‘https://randomuser.me/api/portraits/women/65.jpg',
text:
“This guy does everything he can to get the job done and done right. This is the second time I’ve hired him, and I’ll hire him again in the future.”,
},
{
name: ‘Jonathan Nunfiez’,
position: ‘Graphic Designer’,
photo: ‘https://randomuser.me/api/portraits/men/43.jpg',
text:
“I had my concerns that due to a tight deadline this project can’t be done. But this guy proved me wrong not only he delivered an outstanding work but he managed to deliver 1 day prior to the deadline. And when I asked for some revisions he made them in MINUTES. I’m looking forward to work with him again and I totally recommend him. Thanks again!”,
},
{
name: ‘Sasha Ho’,
position: ‘Accountant’,
photo:
https://images.pexels.com/photos/415829/pexels-photo-415829.jpeg?h=350&auto=compress&cs=tinysrgb',
text:
‘This guy is a top notch designer and front end developer. He communicates well, works fast and produces quality work. We have been lucky to work with him!’,
},
{
name: ‘Veeti Seppanen’,
position: ‘Director’,
photo: ‘https://randomuser.me/api/portraits/men/97.jpg',
text:
‘This guy is a young and talented IT professional, proactive and responsible, with a strong work ethic. He is very strong in PSD2HTML conversions and HTML/CSS technology. He is a quick learner, eager to learn new technologies. He is focused and has the good dynamics to achieve due dates and outstanding results.’,
},
]
let index= 0;
let munMax=100;

getData();
function getData(){
let {name, position, photo, text} =datas[index];

imgEl.src=photo;
h3El.innerText = name;
pEl.innerText =text;
pinfoEl.innerText = position;

index++;
if (index > datas.length - 1) {
index= 0;
}
}
///////////在中间加这段代码是为了在显示第一个人的信息的时候百分比能显示出来////////////////
let i=0;
let id=setInterval(() => {
if(i<=100){
span.innerText=i+’%’;
i++;
}
},110)
// /////////////////////////
setInterval(() => {
getData();

let i=1;
let id=setInterval(() => {
span.innerText=i+’%’;
i++;
if(i>100){
clearInterval(id);
i=0;
}
}, 200);

}, 20000);

1
2
3
4
5

### Random Image Feed

演示参考地址: https://50projects50days.com/projects/random-image-feed/

****HTML

Random Image Feed

CSS*********
body {
font-family: ‘Roboto’, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
margin: 0;
}

.title{
margin-top: 10;
text-align: center;
}

.container{
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;

}

.container img{
object-fit: cover;
margin: 10px;
height: 300px;
width: 300px;
max-width: 100%;

}

JS*
const container = document.querySelector(‘.container’)
const unsplashURL = ‘https://source.unsplash.com/random/'
const count=15;

for(let i=0; i<15; i++){
let img=document.createElement(‘img’);
img.src=${unsplashURL}${getRandomSize()};
container.appendChild(img)
}

function getRandomSize(){
return ${getRandomNum()}x${getRandomNum()}
}
function getRandomNum(){
return Math.floor(Math.random()*10+ 300);

}

1
2
3
4
5
6
7

### Todo List

演示参考地址:https://50projects50days.com/projects/todo-list/

涉及到locaolstorage方面的内容

*HTML

todos

Left click to toggle completed.
Right click to delete todo

*****CSS8
body{
display: flex;

justify-content: center;
text-align: center;
height: 100vh;

margin: 0;
}

h1{
margin-top: 15px;
color:#DBC7ED;
font-size: 130px;
letter-spacing: 3px;
}

.inputcontainer{
box-shadow: 2px 3px 12px rgba(0,0,0, 0.2);
width:500px;
max-width: 100%;
margin-bottom: 30px;
}

input {
border: none;
color: #444;
font-size: 2rem;
padding: 0.5rem 2rem;
display: block;
width: 100%;
outline: none;
}

input::placeholder {
color: #d5d5d5;
}
input:focus{
border: solid 2px #DBC7ED;
}

ul{
background-color: #fff;
padding: 0;
margin: 0;
list-style-type: none;
}

li{
font-size: 35px;
border-bottom: 1px solid rgba(88, 86, 86, 0.133);
padding: 12px;
}

li.completed{
color:rgb(248, 66, 10);
text-decoration: line-through;

}

li:first-of-type{
border-top: 1px solid rgba(88, 86, 86, 0.133);
}
small{
font-size: 18px;
max-width: 350px;
color:rgb(121, 118, 118);
}

small.last{
margin-top: 900px;
}

**jS
const input = document.getElementById(‘input’);
const ul = document.querySelector(‘ul’);
const lis = document.querySelectorAll(‘li’);

let notes = JSON.parse(localStorage.getItem(‘notes’));
notes.forEach(note=>{
addNote(note);
})

input.addEventListener(‘keyup’ ,(e)=>{
if(e.keyCode==13){
addNote();
}
})

function addNote(note){
let notetext = input.value;
//这个判断可将以前保存在localstarage里面的数据显示出来。
if(note){
notetext = note.text;
}

if(notetext){
let li =document.createElement(‘li’);
li.innerHTML = notetext;

li.addEventListener('click', ()=>{
  li.classList.toggle('completed');
  upLS();
})

li.addEventListener('contextmenu' ,(e)=>{
e.preventDefault();
  li.remove();
  upLS();
})

ul.appendChild(li);
input.value='';
upLS();

}
}

////更新Locastorage数据库
function upLS(){
let notes = [];
let lis = document.querySelectorAll(‘li’)
lis.forEach(li=>{
notes.push({
text: li.innerText,
completed: li.classList.contains(‘completed’)
})
})

localStorage.setItem(‘notes’, JSON.stringify(notes))
}


JS事件

button.onclick = sayThanks; //sayThanks是函数名,不需要括号

//这里需要括号

移除相同的函数

要把处理事件的函数附上函数名,要不然不是对同一个对象进行操作,则无法移除。

1
2
3
4
5
function handler(){
alert('Thanks!');
}
input.addEventListener('click', handler);
input.removeEventListener('click', handler); 第二个参数只能是参数名,要不然无法移除

event.currentTarget

event.currentTarget属性可以获取处理事件的元素,和this的作用相同,当this是一个箭头函数,或者this的指向发生改变,可以使用event.currentTarget获取到元素。

文档的修改

插入方法

标签和文本的插入:使用before、prepend、append、after方法

1625707429904

HTML代码的插入:insertAdjacentHTML(where,html)

where的值可以是“beforeend”,”beforebegin”、“afetrend”、“afterbegin”

节点的移除

node.remove();

克隆节点elem.cloneNode(true)

举例:div2 = div.cloneNode(true),参数true表明会克隆div的所有特性和子元素,false则表明不克隆子元素

DocumentFragment

DocumentFragment 是一个特殊的 DOM 节点,用作来传递节点列表的包装器(wrapper)。

我们可以向其附加其他节点,但是当我们将其插入某个位置时,则会插入其内容。

例如,下面这段代码中的 getListContent 会生成带有 列表项的片段,然后将其插入到 中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<ul id="ul"></ul>

<script>
function getListContent() {
let fragment = new DocumentFragment();

for(let i=1; i<=3; i++) {
let li = document.createElement('li');
li.append(i);
fragment.append(li);
}

return fragment;
}

ul.append(getListContent()); // (*)
</script>

parentElem.apendChild(node)

在父元素parentElment的最后插入一个位置插入node子元素。

小例子

动态创建列表

1
2
3
4
5
6
7
8
9
let ul = document.createElement('ul');
document.body.append(ul);
while(true){
let value =prompt("请输入内容", '');
if(!value){
break;
}
ul.insertAdjacentHTML('afterbegin',`<li>${value}</li>`);
}

从对象创建树

元素的大小和滚动

检查一个元素是否被隐藏

1
2
3
function isHidden(elem){
return !elem.offsetWidth && elem.offsetHeight
}

getComputeStyle(elem).width和elem.clientWidth之间有什么不同点

1、elem.clientWidth的值是数值,而getComputedStyle(elem).width是返回一个以px结尾的字符串。

2、getComputeStyle可能会返回非数值的width,例如内联元素的“auto”;

3、clientWidth是元素的内部区域加上padding的距离,而getComputeStyle(elem).width是内部区域(具有标准的box-sizing),不包含padding;

4、getComputeStyle(elem)计算得到的宽度有的浏览器包含进度条,有的浏览器不包含进度条,clientWidth始终不包含滚动条的宽度。

1626400220362

window.innnerWidth和document.documentElement.clientWidth的区别

前者包含整个页面的宽度,后者不包括进度条。

ScrollTo、ScrollBy的区别

ScrollT(pagex, pagey),j滚动到相对于整个文档的位置

ScrollBy(x,y),以当前所在的位置为参考点,移动到(x,y)位置

scrolltoView(true/false)

elem.scrolltoView(true),true是默认值,会将当前的元素定位到窗口的顶部,反之为false则定位到底部。

禁止滚动

document.body.style.overflow= “hidden”; 禁止滚动

document.body.style.overflow = ‘’; 解除禁止滚动

elementFromPoint(x,y)

document.elementFromPoint(x,y)会返回在窗口坐标(x,y)出嵌套最多的元素

1
2
3
4
5
let centerX = document.documentElement.clientWdith/2;
let centerY = document.documentElement.clientheight/2;
let elem =document.elementFromPiont(centerX, centerY);
elem.style.background = "red";
alert(elem.tagName);

上面的代码会高亮显示并输出位于窗口中间的标签。

getBoundingClientRect()

该方法没有参数,可返回以下值,通过获取的值可以计算元素的坐标

计算div的坐标

1
2
3
4
5
6
let x= div.getBoundingClientRect().left + document.documentElementScrollLeft;
let y = div.getBoundingClientRect().top + document.documentElementScrollHeight;

注意:documentElementScrollLfet/height是IE8之前的
IE9及之后使用window.pageXOffset和window.pageYOffset

计算任意一点的坐标

1
2
3
4
document.onclick = function(this){
coords.innerHTML = this.clientX +":" + this.clientY;
}
点击屏幕上的某一点,可显示出当前坐标,前提是没有滚动体条。

JS实现懒加载

网页显示图片的时候会通过src属性去加载图片,未防止报错,我们可以先将src的地址置空,然后再自定义一个data属性,在以后显示到这张图片的时候,把src的地址重新指向data的地址,就可以获得并显示图片。

1
2
3
4
5
6
7
8
9
10
11
12
13
HTML部分
<ul>
<li><img src="" data="./img/1.jpg" alt=""></li>
<li><img src="" data="./img/2.jpg" alt=""></li>
<li><img src="" data="./img/10.jpg" alt=""></li>
<li><img src="" data="./img/3.jpg" alt=""></li>
<li><img src="" data="./img/4.jpg" alt=""></li>
<li><img src="" data="./img/5.jpg" alt=""></li>
<li><img src="" data="./img/6.jpg" alt=""></li>
<li><img src="" data="./img/7.jpg" alt=""></li>
<li><img src="" data="./img/8.jpg" alt=""></li>
<li><img src="" data="./img/9.jpg" alt=""></li>
</ul>

上一下图,声明这个图不是我画的,我对各种距离是有点晕的,感谢这张图解救了我。

实现懒加载的关键是判断什么时候开始加载,想象一下,在滚动鼠标浏览图片的时候,当下一张图片要进入页面的时候你要保证它这个时候已经加载出来了,这时候的条件是什么呢?就是当前的视口大小+已经滚动的距离>下一张图片到顶部的距离(表明下一张图片开始露头了)

onload事件会在页面或者图像加载完成后立即发生

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<script>
window.onload = function(){
// 获取图片列表,即img标签列表
let imgs = document.querySelectorAll('img');
// 懒加载实现
function lazyload(imgs){
// 可视区域高度
let viewHeight = window.innerHeight;
//滚动区域高度
let scrollTop= document.documentElement.scrollTop || document.body.scrollTop;
for(let i=0;i<imgs.length;i++){
let offsetTop = imgs[i].offsetTop;
//关键性代码
//图片距离顶部的距离大于可视区域和滚动区域之和时懒加载
if ((viewHeight+scrollTop)>offsetTop) {
imgs[i].src = imgs[i].getAttribute('data')
}
}
}
lazyload(imgs);//保证在未滚动之前先显示该显示的画面
// 滚屏的时候执行该函数
window.onscroll =function(){
lazyload(imgs);
}
}
</script>

JS的数据类型

基本数据类型六种:string、number、boolean、null、undefined、symbol

对象类型:也叫引用类型,主要包括Array和function

为什么说JS是弱类型的语言

js在声明变量的时候并没有预先确定的类型,变量的值就是它的类型,同一值在不同的情况下会发生强制转换变成不同的类型。所以说它是弱类型的语言。

js强制转换的规则

js有一个内置ToPrimitive(obj,type)算法,用于将引用引用类型转换成基本类型

String 运算符号转换规则

null=>”null” undefined=>undefined true=>’trur’ false=>’false’

number运算符强制转换

null=>0; undefined=>NaN; ture=>1; false=>0;

字符串转换遵循数字常量规则,转换失败返回NaN

Boolean

除了undefined/null/0/-0/NaN/空字符串为false,其他为true.

js强制转换的不同场景

什么时候自动转换成string类型?

字符串类型的而转换,主要发生在字符串的加法运算中

1
2
3
4
5
'2' + 1// '21'
'2' + true// "2true"
'2' + false// "2false"
'2' + undefined// "2undefined"
'2' + null// "2null"

运算隐式转换

+号左右两边分别进行取值,进行ToPrimitive()操作

分别获取左右转换之后的值,如果存在String,则对其进行Tostring处理后进行拼接

其他都按照ToNumber处理(调用valueOf)

在转换时ToPrimitive,除去Date为string外,其余都按照ToNumber处理

什么时候自动转换成Number

有加法运算符(-*也可以),但是没有String类型的时候,会优先转换成数字类型

toString和String的区别

toString不可以将null和undefined转换成字符串,可以带进制转换,如334.toString(2),

而string可以转换null和undefined,但是不可以进行进制转换

用js创建表格并在特定位置添加背景颜色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
HTML代码
<table width="200px" height="200px" border=" 1px" cellspacing='0'></table>

JS代码
let table = document.querySelector("table");
for (let i = 1; i <= 5; i++) {
let tr = table.appendChild(document.createElement("tr"));
for (let j= 1; j <= 5; j++) {
添加背景颜色的第一种写法

// i===j? tr.insertAdjacentHTML('beforeend',`<td style="background-color: red">${j}:${i}</td>`) : tr.insertAdjacentHTML('beforeend',`<td>${j}:${i}</td>`)

添加背景颜色的第二种写法
tr.insertAdjacentHTML('beforeend', `<td style=${i===j ? 'background-color:red' : ''}></td>`)
}
}
添加背景颜色的第三种写法
// for (let i = 0; i<table.rows.length; i++){
// table.rows[i].cells[i].style.backgroundColor="red";
// }

运行结果

1625292413967

1、输入斐波那契数列的个数,返回数列成员

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function fib(max){
let a=0,b=1;
let arr=[a,b];
while(arr.length<max){
[a,b]=[b,a+b];
arr.push(b)
}
return arr;
}
console.log(fib(5));

// 测试:
fib(5); // [0, 1, 1, 2, 3]
fib(10); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

2、给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
方法一
function twoSum(arr, value) {
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length-1; j++) {
if (arr[i] + arr[j] === value) {
return [i, j]
}
}
}
return ("没有找到")
}
let arr = [1,2,5,2,1, 6]
console.log(twoSum(arr, 7));

方法二

function twoSum (arr, value) {
const mapArr = new Map();
for ( let i = 0 ; i < arr.length; i++) {
let n1 = arr[i]
let n2 = value - arr[i]
if (mapArr.has(n2)) {
return [mapArr.get(n2), i]
}else {
mapArr.set(n1,i) //将索引作为值,方便通过get取到
}
}
}

3、输出一篇英语文章中出现次数最多的单词

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//找出一篇英文文章中出现次数最多的单词
function getMaxTimesWords(article) {
if (article === null) {
return;
}
//遍历每一个单词,创建一个map对象来存储记录每个单词出现的次数key: "string", value: number
let newMap = new Map();
let words = article.split(' ');
for (let i = 0; i < words.length; i++) {
if (!newMap.has(words[i])) {
newMap.set(words[i], 1);
} else {
newMap.set(words[i], newMap.get(words[i]) + 1);
}
}

let item = { key: '', value: 0 };
newMap.forEach((value, key) => {
value > item.value && ((item.value = value), (item.key = key));
});
return item;
}
let article = 'i am a dog, i am a cat , i has a dolphin ha ha ha haha hah ha ';
console.log(getMaxTimesWords(article));

使用Promise封装Ajax一部请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function ajax(url){
return new Promise((resolve,reject)=>{
let xhr = new XMLHttpRequest();
xhr.open('GET',url);
xhr.send();
xhr.onload=function(){
if(this.status==200){
resolve(JSON.parse(this.response))
}else{
reject('加载失败');
}
};
xhr.oneroor = function(){
reject(this)
}

})
}

let url = "https://localhost:8888/php";
ajax(`${url}/user.php?name=后盾人`).then(
value=>{
console.log(value);
},
reason=>{
console.log(reason+'abd');
}
);

promise多种错误检测与catch使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
new  Promise((resolve,reject)=>{
// reject('rejected')
resolve('成功');
}).then(value=>{
return new Promise((resolve,reject)=>{
reject('错误');

});
})
.then(value=>{
console.log(value);
})
.catch(error=>{
console.log(error);
})
推荐把catch放在代码的后面可以对代码错误进行统一处理,如果在catch之前定义有处理错误的代码,则走错误代码,否则走catch

Promise异步加载图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function loadImage(src){
return new Promise((resolve, reject)=>{
const image=new Image();
image.src = src;
image.onload = ()=>{ resolve(image)};
image.onerror=reject; //这个地方的reject为什么没有加开罗好
document.body.appendChild(image);
});
}

loadImage('tile.png').then(image=>{
image.style.border="solid 7px red";
});


封装settimeout定时器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function timeout(delay=2000) {
// return new Promise((resolve=>{
// setTimeout(resolve, delay)
// }))
return new Promise((resolve,reject)=>{
setTimeout(resolve, delay);
})
}

timeout(2000)
.then(()=>{console.log("houdunren,com");
return timeout(2000);
})
.then(value=>{
console.log("hdcms.com");
})

构建扁平化的setinterval

Script脚本的Promise加载引擎

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function loadScript(src){
return new Promise((resolve,reject)=>{
const script = document.createElement('script');
script.src =src;
script.onload= ()=>{resolve(script)};
script.onerror=reject;
document.body.appendChild(script);

});
}

loadScript("js/test.js").then(script=>{
return loadScript("js/main.js");
}).then(script=>{
houdunren();
})

Promise.resolve缓存后台数据

async和await语法糖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
async function hd(){
let name =await new Promise(resolve=>{
setTimeout(() => {
resolve('第二个');

}, 2000);
});
let site = await new Promise(resolve=>{
setTimeout(() => {
resolve(name+"houdunren.com")//能够接到上面的name
}, 1000);
})
console.log(site);
}

hd()

await和async进行异步请求

获取QQ空间访问量

1
2
3
4
5
6
async function getUser(name){
let url ='https://api.muxiaoguo.cn/api/qzonetors';
let user = await axios.get(`${url}?qq=${name}`)
console.log(user.data.data);
}
getUser('2508026070')

async延时函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
async function sleep(delay=2000){
return new Promise(resolve=>{
setTimeout(()=> {
resolve(); //记住状态要写,要不然后面的代码不执行
},delay);
})
}
async function show(){
for (const user of ['古人',"后人"]) {
await sleep();
console.log(user);
}
}
show();

await制作加载进度条

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
html部分
<div id="loading">0%</div>

css部分
div{
background-color: rgb(185, 125, 241);
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
color:aliceblue
}

JS部分
//使用axios调用接口的时候有个问题,它只能调用一次,后面的调不出来
async function getUser(name){
let url ='https://api.muxiaoguo.cn/api/qzonetors';
return await axios.get(`${url}?qq=${name}`);
}

async function loaderUser(users){
for (let i=0; i<users.length; i++){
let user = await getUser(users[i]);]
let progress = ((i+1)/users.length)*100;
loading.style.width = progress +"%";
loading.innerHTML = progress+"%"
}
}
loaderUser(['1626676263', '1908948984'])

await与class的结合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class User{
constructor(name){
this.name =name;
}
then(resolve,reject){
let url ='https://api.muxiaoguo.cn/api/qzonetors';
let result=axios.get(`${url}?qq=${this.name}`);
resolve(result);//注意这里要将状态的值返回回去,要不然下面接不到就不会执行
}
}
async function get(){
let user = await new User("1626676263");
console.log(user.data.data);
}
//调用函数
get()

异步封装在类内部

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class User{
constructor(name){
this.name =name;
}
async get (name){
let url ='https://api.muxiaoguo.cn/api/qzonetors';
let result= await axios.get(`${url}?qq=${name}`);
result.data.data.todaycount+= "多少次";
return result
}
}
new User().get('1626676263').then(result=>{
console.log(result);
})