1.Expanding Cards
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:弹性盒子布局中的
flex
属性:让所有弹性盒模型对象的子元素都有雷同的长度,且疏忽它们外部的内容。 - JavaScript:利用
[].filter.call()
办法可疾速实现简略的选项卡切换。如上述示例源码:
const panelItems = document.querySelectorAll(".container > .panel");panelItems.forEach(item => { item.addEventListener('click',() => { [].filter.call(item.parentElement.children,el => el !== item).forEach(el => el.classList.remove('active')); item.classList.add('active') });});
2.Progress Steps
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:
CSS
变量的用法以及弹性盒子垂直程度居中外加伪元素的用法。 - JavaScript:计算进度条的宽度,类名的操作。如上述示例局部源码如下:
function handleClass(el){ let methods = { addClass, removeClass }; function addClass(c){ el.classList.add(c); return methods; }; function removeClass(c){ el.classList.remove(c); return methods; } return methods}
3.Rotating Navigation Animation
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:CSS弹性盒子布局加
rotate
动画。 - JavaScript:增加和移除类名的操作。如上述示例局部源码如下:
const addClass = (el,className) => el.classList.add(className);const removeClass = (el,className) => el.classList.remove(className);
4.hidden-search-widget
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:CSS过渡动画 + 宽度的更改 +
input
的placeholder
款式。 - JavaScript:增加和移除类名的操作。如上述示例局部源码如下:
.search.active > .input { width: 240px;}.search.active > .search-btn { transform: translateX(238px);}.search > .search-btn,.search > .input { border: none; width: 45px; height: 45px; outline: none; transition: all .3s cubic-bezier(0.25, 0.46, 0.45, 0.94); border-radius: 8px;}
searchBtn.addEventListener('click',() => { searchContainer.classList.toggle('active'); searchInput.focus();})
5.Blurry Loading
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:
CSS filter
属性的用法;。 - JavaScript:定时器加动静设置款式。如上述示例局部源码如下:
let load = 0;let timer = null;let blurryLoadingHandler = function(){ load++; if(load > 99){ clearTimeout(timer) }else{ timer = setTimeout(blurryLoadingHandler,20); } text.textContent = `页面加载${ load }%`; text.style.opacity = scale(load,0,100,1,0); bg.style.filter = `blur(${scale(load,0,100,20,0)}px)`;}blurryLoadingHandler();
这里有一个十分重要的工具函数(后续有好几个示例都用到了这个工具函数),如下所示:
const scale = (n,inMin,inMax,outerMin,outerMax) => (n - inMin) * (outerMax - outerMin) / (inMax - inMin) + outerMin;
这个工具函数的作用就是将一个范畴数字映射到另一个数字范畴。比方说,将1 ~ 100
的数字范畴映射到0 ~ 1
之间。
详情。
6.Scroll Animation
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:
CSS
位移动画。 - JavaScript:动态创建元素+元素滚动事件监听+视图可见区域的判断 + 防抖函数。如上述示例局部源码如下:
function debounce(fn,time = 100){ let timer = null; return function(){ if(timer)clearTimeout(timer); timer = setTimeout(fn,time); }}let triggerBottom = window.innerHeight / 5 * 4;boxElements.forEach((box,index) => { const top = box.getBoundingClientRect().top; if(top <= triggerBottom){ box.classList.add('show'); }else{ box.classList.remove('show'); }})
7. Split Landing Page
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:
CSS
过渡特效 + 弹性盒子垂直程度居中 +CSS
定位 + 宽度的更改。 - JavaScript:鼠标悬浮事件 + 类名的操作。如上述示例局部源码如下:
HTMLElement.prototype.addClass = function(className) { this.classList.add(className);};HTMLElement.prototype.removeClass = function(className){ this.classList.remove(className);}const on = (el,type,handler,useCapture = false) => { if(el && type && handler) { el.addEventListener(type,handler,useCapture); }}on(leftSplit,'mouseenter',() => container.addClass('hover-left'));on(leftSplit,'mouseleave',() => container.removeClass('hover-left'));on(rightSplit,'mouseenter',() => container.addClass('hover-right'));on(rightSplit,'mouseleave',() => container.removeClass('hover-right'));
从这个示例,我也晓得了mouseenter、mouseleave
和mouseover、mouseout
的区别,总结如下:
- enter只触发1次,只有等到鼠标来到了指标元素之后再进入才会持续触发,同理leave也是如此了解。而over与out就是一直的触发。
- enter进入子元素,通过e.target也无奈辨别是移入/移出子元素还是父元素,而over与out则能够辨别。
8.Form Wave
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:
CSS
突变 + 弹性盒子垂直程度居中 +CSS
过渡动画 +CSS
位移变换 + 关注焦点伪类选择器与同级元素选择器的用法。 - JavaScript:字符串替换成标签 + 动态创建元素。如上述示例局部源码如下:
const createLetter = v => v.split("").map((letter,idx) => `<span style="transition-delay:${ idx * 50 }ms">${ letter }</span>`).join("");
9.Sound Board
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:
CSS
突变 + 弹性盒子垂直程度居中 + 根本款式。 - JavaScript:动态创建元素 + 播放音频(
audio
标签)。如上述示例局部源码如下:
sounds.forEach(sound => { const btn = create('button'); btn.textContent = sound; btn.type = "button"; const audio = create('audio'); audio.src = "./audio/" + sound + '.mp3'; audio.id = sound; btn.addEventListener('click',() => { stopSounds(); $('#' + sound).play(); }); buttonContainer.appendChild(btn); buttonContainer.insertAdjacentElement('beforebegin',audio);});
10. Dad Jokes
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:
CSS
突变 + 弹性盒子垂直程度居中 + 根本款式。 - JavaScript:事件监听 +
fetch API
申请接口。如上述示例局部源码如下:
const api = 'https://icanhazdadjoke.com';const on = (el,type,handler,useCapture = false) => { if(el && type && handler){ el.addEventListener(type,handler,useCapture); }}on(getJokeBtn,'click',request);request();async function request(){ const res = await fetch(api,headerConfig); const data = await res.json(); content.innerHTML = data.joke;}
11. Event Keycodes
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:
CSS
突变 + 弹性盒子垂直程度居中 + 根本款式。 - JavaScript:键盘事件监听 + 事件对象的属性。如上述示例局部源码如下:
const container = document.querySelector('#container');window.addEventListener("keydown",event => { createKeyCodeTemplate(event);});function createKeyCodeTemplate(e){ const { key,keyCode,code } = e; let template = ""; [ { title:"event.key", content:key === " " ? "Space" : key }, { title:"event.keyCode", content:keyCode }, { title:"event.code", content:code } ].forEach(value => { template += `<div class="key"><small>${ value.title }</small>${ value.content }</div>`; }); container.innerHTML = template;}
12. Faq Collapse
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:
font-awesome
字体库的应用 + 伪元素选择器 + 定位 +CSS
突变 + 根本款式。 - JavaScript:动态创建元素 + 类名的切换 + 事件代理。如上述示例局部源码如下:
const faqs = document.querySelectorAll('.faq-container > .faq');container.addEventListener('click',e => { if(e.target.className.indexOf('faq-icon') > -1){ faqs[[].indexOf.call(faqs,e.target.parentElement)].classList.toggle('active'); }});
13. Random Choice Picker
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式。
- JavaScript:动态创建元素 + 类名的切换 + 提早定时器的用法 + 随机数 + 键盘事件的监听。如上述示例局部源码如下:
function createTags(value,splitSymbol){ if(!value || !value.length)return; const words = value.split(splitSymbol).map(v => v.trim()).filter(v => v); tags.innerHTML = ''; words.forEach(word => { const tag = document.createElement('span'); tag.classList.add('tag'); tag.innerText = word; tags.appendChild(tag); })}function randomTag(){ const time = 50; let timer = null; let randomHighLight = () => { const randomTagElement = pickerRandomTag(); highLightTag(randomTagElement); timer = setTimeout(randomHighLight,100); setTimeout(() => { unHighLightTag(randomTagElement); },100); } randomHighLight(); setTimeout(() => { clearTimeout(timer); setTimeout(() => { const randomTagElement = pickerRandomTag(); highLightTag(randomTagElement); },100); },time * 100);}function pickerRandomTag(){ const tagElements = document.querySelectorAll('#tags .tag'); return tagElements[Math.floor(Math.random() * tagElements.length)];}
14. Animated Navigation
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式 + 定位 + 位移变换以及角度旋转。
- JavaScript:类名的切换。如上述示例局部源码如下:
toggle.addEventListener('click',() => nav.classList.toggle('active'));
15. Incrementing Counter
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式 +
CSS
突变 +font-awesome
字体库的应用。 - JavaScript:动态创建元素 + 定时器实现增量相加。如上述示例局部源码如下:
function updateCounterHandler() { const counters_elements = document.querySelectorAll('.counter'); counters_elements.forEach(element => { element.textContent = '0'; const updateCounter = () => { const value = +element.getAttribute('data-count'); const textContent = +element.textContent; const increment = value / 100; if (textContent < value) { element.textContent = `${Math.ceil(increment + textContent)}`; setTimeout(updateCounter, 10); } else { element.textContent = value; } } updateCounter(); });}
16. Drink Water
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式 +
CSS
突变 +CSS
过渡特效。 - JavaScript:正则表达式 + 循环 + 款式与内容的设置。如上述示例局部源码如下:
if (actives.length === l) { setHeightVisible('0', 'hidden', '350px', 'visible'); setTextContent("100%", "0L"); } else if (actives.length === 0) { setHeightVisible('350px', 'visible', '0', 'hidden'); setTextContent("12.5%", "2L"); } else { const h1 = unitHei * (l - actives.length) + 'px'; const h2 = unitHei * actives.length + 'px'; setHeightVisible(h1, 'visible', h2, 'visible'); const t1 = (unitHei * actives.length / 350) * 100 + "%"; const t2 = (cups[i].textContent.replace(/ml/, "").replace(/\s+/, "") - 0) * (l - actives.length) / 1000 + 'L'; setTextContent(t1, t2);}
17. movie-app
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式 +
CSS
突变 +CSS
过渡特效 + 革除浮动。 - JavaScript:接口申请 + 键盘事件的监听。如上述示例局部源码如下:
search.addEventListener('keydown',e => { if(e.keyCode === 13){ let value = e.target.value.replace(/\s+/,""); if(value){ getMovies(SEARCH_API + value); setTimeout(() => { e.target.value = ""; },1000); }else{ window.location.reload(true); } } })
PS:这个示例成果因为接口拜访受限,须要翻墙拜访。
18. background-slider
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式 +
CSS
突变 + 暗影成果 + 定位 + 伪元素选择器。 - JavaScript:背景设置与类名的操作。如上述示例局部源码如下:
let currentActive = 0;function setBackgroundImage(){ const url = slideItems[currentActive].style.backgroundImage; background.style.backgroundImage = url;}function setSlideItem(){ const currentSlide = slideItems[currentActive]; const siblings = [].filter.call(slideItems,slide => slide !== currentSlide); currentSlide.classList.add('active'); siblings.forEach(slide => slide.classList.remove('active'));}
19. theme-clock
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式 +
CSS
变量 + 暗影成果 + 定位。 - JavaScript:中英文的切换以及主题模式的切换,还有日期对象的解决。如上述示例局部源码如下:
function setCurrentDate(){ const date = new Date(); const month = date.getMonth(); const day = date.getDay(); const time = date.getDate(); const hour = date.getHours(); const hourForClock = hour % 12; const minute = date.getMinutes(); const second = date.getSeconds(); const amPm = hour >= 12 ? langText[currentLang]['time-after-text'] : langText[currentLang]['time-before-text']; const w = currentLang === 'zh' ? dayZHs : days; const m = currentLang === 'zh' ? monthZHs : months; const values = [ `translate(-50%,-100%) rotate(${ scale(hourForClock,0,11,0,360) }deg)`, `translate(-50%,-100%) rotate(${ scale(minute,0,59,0,360) }deg)`, `translate(-50%,-100%) rotate(${ scale(second,0,59,0,360) }deg)` ]; [hourEl,minuteEl,secondEl].forEach((item,index) => setTransForm(item,values[index])); timeEl.innerHTML = `${ hour }:${ minute >= 10 ? minute : '0' + minute } ${ amPm }`; dateEl.innerHTML = `${w[day]},${ m[month]}<span class="circle">${ time }</span>${ langText[currentLang]['date-day-text'] }`; timer = setTimeout(setCurrentDate,1000);}
PS:本示例也用到了与示例5一样的工具函数scale
函数
20. button-ripple-effect
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式 +
CSS
突变 +CSS
动画。 - JavaScript:坐标的计算 + 偏移 + 定时器。如上述示例局部源码如下:
const x = e.clientX;const y = e.clientY;const left = this.offsetLeft;const top = this.offsetTop;const circleX = x - left;const circleY = y - top;const span = document.createElement('span');span.classList.add('circle');span.style.left = circleX + 'px';span.style.top = circleY + 'px';this.appendChild(span);setTimeout(() => span.remove(),1000);
21. drawing-app
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式。
- JavaScript:
canvas API
+mouse
事件以及计算x
与y
坐标 +ewColorPicker
的用法。如上述示例局部源码如下:
function mouseDownHandler(e){ isPressed = true; x = e.offsetX; y = e.offsetY;}function throttle(fn,wait = 100){ let done = false; return (...args) => { if(!done){ fn.call(this,args); done = true; } setTimeout(() => { done = false; },wait); }}
22. drag-n-drop
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式 +
CSS
突变 +CSS
弹性盒子布局。 - JavaScript:
drag event API
+ 随机生成图片。如上述示例局部源码如下:
function onDragStart(){ this.classList.add('drag-move'); setTimeout(() => this.className = "invisible",200);}function onDragEnd(){ this.classList.add("drag-fill");}function onDragOver(e){ e.preventDefault();}function onDragEnter(e){ e.preventDefault(); this.classList.add('drag-active');}function onDragLeave(){ this.className = "drag-item";}function onDrop(){ this.className = "drag-item"; this.appendChild(dragFill);}
23. content-placholder
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式 +
CSS
突变 +CSS
卡片款式。 - JavaScript:骨架屏加载成果。如上述示例局部源码如下:
animated_bgs.forEach(bg => bg.classList.remove("animated-bg"));animated_bgs_texts.forEach(text => text.classList.remove("animated-bg-text"));
24. sticky-navbar
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式 +
CSS
突变 + 固定定位导航。 - JavaScript:滚动事件。如上述示例局部源码如下:
window.addEventListener("scroll",e => { if(window.scrollY > nav.offsetHeight + 100) { nav.classList.add("active"); }else{ nav.classList.remove("active"); }})
PS:这里也做了挪动端的布局。
25. double-slider
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式 +
CSS
突变 + 位移变换。 - JavaScript:轮播图的实现思路,次要还是利用
transformY
挪动端应用transformX
。如上述示例局部源码如下:
function setTransform(){ let translate = isHorizontal() ? "translateX" : "translateY"; leftSlide.style.transform = `${ translate }(${position * currentIndex}px)`; rightSlide.style.transform = `${ translate }(${-(position * currentIndex)}px)`;}
26. toast-notification
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式 + 音讯提示框的根本款式。
- JavaScript:封装一个随机创立音讯提示框。如上述示例局部源码如下:
function createNotification({message = null,type = null,auto = false,autoTime = 1000,left = 0,top = 0}){ const toastItem = createEle("div"); let closeItem = null; if(!auto){ closeItem = createEle("span"); closeItem.innerHTML = "×"; closeItem.className = "toast-close-btn"; } toastItem.className = `toast toast-${type}`; toastItem.textContent = message; if(closeItem)toastItem.appendChild(closeItem); container.appendChild(toastItem); const leftValue = (left - toastItem.clientWidth) <= 0 ? 0 : left - toastItem.clientWidth - 30; const topValue = (top - toastItem.clientHeight) <= 0 ? 0 : top - toastItem.clientHeight - 30; toastItem.style.left = leftValue + 'px'; toastItem.style.top = topValue + 'px'; if(auto){ setTimeout(() => { toastItem.remove(); },autoTime); }else{ closeItem.addEventListener("click",() => { toastItem.remove(); }); } }
音讯提示框实现思路能够参考这篇文章。
27. github-profiles
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式。
- JavaScript:
try-catch
解决异样语法 +axios API
申请github API
+async-await
语法。如上述示例局部源码如下:
async function getRepoList(username){ try { const { data } = await axios(githubAPI + username + '/repos?sort=created'); addRepoList(data); } catch (error) { if(error.response.status == 404){ createErrorCard("查找仓库出错!"); } }}
28. double-click-heart
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式 +
CSS
画爱心。 - JavaScript:事件次数的计算。如上述示例局部源码如下:
function clickHandler(e){ if(clickTime === 0){ clickTime = Date.now(); }else{ if(Date.now() - clickTime < 400){ createHeart(e); clickTime = 0; }else{ clickTime = Date.now(); } }}
29. auto-text-effect
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式。
- JavaScript:定时器 + 定时器工夫的计算。如上述示例局部源码如下:
let time = 300 / speed.value;writeText();function writeText(){ text.innerHTML = string.slice(0,idx); idx++; if(idx > string.length){ idx = 1; } setTimeout(writeText,time);}speed.addEventListener("input",e => time = 300 / e.target.value);
30. password generator
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式布局。
- JavaScript:中英文切换 + 抉择框事件监听 + 随机数 +
copy API
。如上述示例局部源码如下:
function getRandomLower(){ // a ~ z 的code为 97 ~ 122 // 可依据charCodeAt()办法获取 return String.fromCharCode(Math.floor(Math.random() * 26) + 97);}function getRandomUpper(){ // A ~ Z 的code为 65 ~ 90 // 可依据charCodeAt()办法获取 return String.fromCharCode(Math.floor(Math.random() * 26) + 65);}function getRandomNumber(){ // 0 ~ 9的code为48 ~ 57 // 可依据charCodeAt()办法获取 return String.fromCharCode(Math.floor(Math.random() * 10) + 48);}
31. good-cheap-fast
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:
CSS
实现开关小组件款式 + 根本布局款式。 - JavaScript:
input
的change
事件的监听。如上述示例局部源码如下:
const checkBoxElements = document.querySelectorAll(".switch-container input[type='checkbox']");checkBoxElements.forEach(item => item.addEventListener("change",e => { const index = Array.from(checkBoxElements).indexOf(e.target); if(Array.from(checkBoxElements).every(v => v.checked)){ if(index === 0){ checkBoxElements[2].checked = false; }else if(index === 1){ checkBoxElements[0].checked = false; }else{ checkBoxElements[1].checked = false; } }}));
32. notes-app
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式 + 卡片布局。
- JavaScript:
marked.js
的应用 +localStorage API
存储数据 + 鼠标光标地位的计算。如上述示例局部源码如下:
on($(".edit", note), "click", e => { const isFocus = textarea.getAttribute("data-focus"); if (isFocus === "false") { textarea.setAttribute("data-focus","true"); if(textarea.classList.contains("hidden")){ textarea.classList.remove("hidden"); } if(!focusStatus){ textarea.value = notes[index].text; } const text = textarea.value.trim(); // console.log(text); if (textarea.setSelectionRange) { textarea.focus(); textarea.setSelectionRange(text.length, text.length); }else if (textarea.createTextRange) { const range = textarea.createTextRange(); range.collapse(true); range.moveEnd('character', text.length); range.moveStart('character', text.length); range.select(); } } else { textarea.setAttribute("data-focus","false"); notes[index].text = textarea.value; main.innerHTML = marked(notes[index].text); setData("notes", notes); }});
33. animated-countdown
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式 + 位移、旋转、缩放动画。
- JavaScript:动画事件 + 动画的创立与重置。如上述示例局部源码如下:
function runAnimation(){ const numArr = $$("span",numGroup); const nextToLast = numArr.length - 1; numArr[0].classList.add("in"); numArr.forEach((num,index) => { num.addEventListener("animationend",e => { const {animationName} = e; if(animationName === "goIn" && index !== nextToLast){ num.classList.remove("in"); num.classList.add("out"); }else if(animationName === "goOut" && num.nextElementSibling){ num.nextElementSibling.classList.add("in"); }else{ counter.classList.add("hide"); final.classList.add("show"); } }) })}function resetAnimation(){ counter.classList.remove("hide"); final.classList.remove("show"); const numArr = $$("span",numGroup); if(numArr){ numArr.forEach(num => num.classList.value = ''); numArr[0].classList.add("in"); }}
34. image-carousel
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式布局。
- JavaScript:定时器实现轮播。如上述示例局部源码如下:
function changeCarouselItem(){ if(currentIndex > carouselItems.length - 1){ currentIndex = 0; }else if(currentIndex < 0){ currentIndex = carouselItems.length - 1; } carousel.style.transform = `translateX(-${ currentIndex * carouselContainer.offsetWidth }px)`;}
PS:这里额定踩了一个定时器的坑,也就是说,比方咱们应用setTimeout模仿实现setInterval办法在这里是会呈现问题的,我在js代码里增加了正文阐明。
// let interval = mySetInterval(run,1000);// Why use this method can't achieve the desired effect?// Use this method as follow to replace window.setInterval,clicked the prev button more to get the stranger effect.// Maybe this method does not conform to the specification,So make sure to use window.setInterval.// function mySetInterval(handler,time = 1000){// let timer = null;// const interval = () => {// handler();// timer = setTimeout(interval,time);// }// interval();// return {// clearMyInterval(){// clearTimeout(timer);// }// }// }
这是因为咱们用setTimeout
实现的定时器并不符合规范,setInterval
默认会有10ms
的提早执行。
参考标准。
35. hover board
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式 +
CSS
突变。 - JavaScript:动态创建元素 + 悬浮事件。如上述示例局部源码如下:
function setColor(element){ element.style.background = `linear-gradient(135deg, ${ randomColor() } 10%, ${ randomColor() } 100%)`; element.style.boxShadow = `0 0 2px ${ randomColor() },0 0 10px ${ randomColor() }`;}function removeColor(element){ element.style.background = `linear-gradient(135deg, #1d064e 10%, #10031a 100%)`; element.style.boxShadow = `0 0 2px #736a85`;}
36. pokedex
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式布局 +
CSS
突变。 - JavaScript:
fetch API
接口申请 + 创立卡片。如上述示例局部源码如下:
function createPokemon(pokemon){ const pokemonItem = document.createElement("div"); pokemonItem.classList.add("pokedex"); const name = pokemon.name[0].toUpperCase() + pokemon.name.slice(1).toLowerCase(); const id = pokemon.id.toString().padStart(3,"0"); const poke_types = pokemon.types.map(type => type.type.name); const type = main_types.find(type => poke_types.indexOf(type) > -1); const color = colors[type]; pokemonItem.style.background = `linear-gradient(135deg, ${ color } 10%, ${ randomColor() } 100%)`; pokemonItem.innerHTML = ` <div class="pokedex-avatar"> <img src="https://pokeres.bastionbot.org/images/pokemon/${pokemon.id}.png" alt="the pokemon"> </div> <div class="info"> <span class="number">#${ id }</span> <h3 class="name">${ name }</h3> <small class="type">Type:<span>${ type }</span></small> </div>`; container.appendChild(pokemonItem);}
特地阐明:接口仿佛不太稳固,兴许是我网络起因,图片没有加载进去。
37. mobile-tab-navigation
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式布局 +
CSS
突变实现手机布局。 - JavaScript:感觉就是挪动端实现一个轮播图切换,利用
opacity
的设置,没什么好说的。如上述示例局部源码如下:
function hideAllElement(nodeList){ nodeList.forEach(item => item.classList.remove("active"));}navItems.forEach((item,index) => { item.addEventListener("click",() => { hideAllElement(navItems); hideAllElement(carouselItems); item.classList.add("active"); carouselItems[index].classList.add("active"); })})
38. password-strength-background
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:其实次要是应用
tailwind.css
这个原子化CSS
框架。 - JavaScript:监听输入框事件,而后扭转背景含糊度。如上述示例局部源码如下:
password.addEventListener("input",e => { const { value } = e.target; const blur = 20 - value.length * 2; background.style.filter = `blur(${ blur }px)`;});
39. 3D-background-boxes
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:
vw、vh
布局 +skew
歪斜变换。 - JavaScript:循环 + 背景图定位的设置。如上述示例局部源码如下:
function createBox(){ 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 * 15 }vw ${ -i * 15 }vh`; boxContainer.appendChild(box); } }}
40. Verify Your Account
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式布局 +
input
的一些特地款式设置。 - JavaScript:
JavaScript focus
事件。如上述示例局部源码如下:
.code-container .code:focus { border-color: #2397ef;}.code::-webkit-outer-spin-button,.code::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0;}.code:valid { border-color: #034775; box-shadow: 0 10px 10px -5px rgba(0, 0, 0, 0.25);}
function onFocusHandler(nodeList){ onFocus(nodeList[0]); nodeList.forEach((node,index) => { node.addEventListener("keydown",e => { // console.log(e.key); if(e.key >= 0 && e.key <= 9){ nodeList[index].value = ""; setTimeout(() => onFocus(nodeList[index + 1]),0); }else{ setTimeout(() => onFocus(nodeList[index - 1]),0); } }) });}function onFocus(node){ if(!node)return; const { nodeName } = node; return nodeName && nodeName.toLowerCase() === "input" && node.focus();}
41. live-user-filter
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式布局 + 滚动条款式。
- JavaScript:
fetch API
接口申请 +input
事件过滤数据。如上述示例局部源码如下:
async function requestData(){ const res = await fetch('https://randomuser.me/api?results=50'); const { results } = await res.json(); result.innerHTML = ""; results.forEach(user => { const listItem = document.createElement("li"); filterData.push(listItem); const { picture:{ large },name:{ first,last },location:{ city,country } } = user; listItem.innerHTML = ` <img src="${ large }" alt="${ first + ' ' + last }" /> <div class="user-info"> <h4>${ first } ${ last }</h4> <p>${ city },${ country }</p> </div> `; result.appendChild(listItem); })}
42. feedback-ui-design
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:
CSS
画爱心 + 根本款式布局。 - JavaScript:选项卡切换性能的实现。如上述示例局部源码如下:
ratingItem.forEach(item => { item.addEventListener("click",e => { siblings(item).forEach(sib => sib.classList.remove("active")); item.classList.add("active"); selectRating = item.innerText; })});send.addEventListener("click",() => { selectRatingItem.innerText = selectRating; sendPage.classList.add("hide"); receivePage.classList.remove("hide");});back.addEventListener("click",() => { selectRating = $(".rating.active").innerText; selectRatingItem.innerText = $(".rating.active").innerText; sendPage.classList.remove("hide"); receivePage.classList.add("hide");});
43. custom-range-slider
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:
input
元素的款式设置(兼容写法) + 根本款式布局。 - JavaScript:
input range
元素的input
事件监听。如上述示例局部源码如下:
input[type="range"]::-webkit-slider-runnable-track { background-image: linear-gradient(135deg, #E2B0FF 10%, #9F44D3 100%); width: 100%; height: 12px; cursor: pointer; border-radius: 4px;}input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 25px; height: 25px; border-radius: 50%; background-image: linear-gradient(135deg, #d9e2e6 10%, #e4e1e4 100%); border: 1px solid #b233e4; cursor: pointer; margin-top: -6px;}
range.addEventListener("input",e => { // string to the number const value = +e.target.value; const label = e.target.nextElementSibling; const range_width = getStyle(e.target,"width");//XXpx const label_width = getStyle(label,"width");//XXpx // Due to contain px,slice the width const num_width = +range_width.slice(0,range_width.length - 2); const num_label_width = +label_width.slice(0,label_width.length - 2); const min = +e.target.min; const max = +e.target.max; const left = value * (num_width / max) - num_label_width / 2 + scale(value,min,max,10,-10); label.style.left = `${left}px`; label.innerHTML = value;});
44. netflix-mobile-navigation
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:导航宽度的变动 +
CSS
突变 + 根本款式布局。 - JavaScript:点击按钮切换导航栏的显隐。如上述示例局部源码如下:
function changeNav(type){ navList.forEach(nav => nav.classList[type === "open" ? "add" : "remove"]("visible"));}
45. quiz-app
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:卡片布局 + 根本款式。
- JavaScript:表单提交 + 选择题的计算。如上述示例局部源码如下:
submit.addEventListener("click",() => { const answer = getSelected(); if(answer){ if(answer === quizData[currentQuestion].correct){ score++; } currentQuestion++; if(currentQuestion > quizData.length - 1){ quizContainer.innerHTML = ` <h2>You answered ${ score } / ${ quizData.length } questions correctly!</h2> <button type="button" class="btn" onclick="location.reload()">reload</button> ` }else{ loadQuiz(); } }})
46. testimonial-box-switcher
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:
CSS
动画 + 宽度的扭转实现进度条 +font-awesome
字体库的应用 + 根本款式布局。 - JavaScript:定时器的用法,留神定时器的执行工夫与设置进度条的执行动画工夫一样。如上述示例局部源码如下:
.progress-bar { width: 100%; height: 4px; background-color: #fff; animation: grow 10s linear infinite; transform-origin: left;}@keyframes grow { 0% { transform: scaleX(0); }}
function updateTestimonial(){ const { text,name,position,photo } = testimonials[currentIndex]; const renderElements = [testimonial,username,role]; userImage.setAttribute("src",photo); order.innerHTML = currentIndex + 1; [text,name,position].forEach((item,index) => renderElements[index].innerHTML = item); currentIndex++; if(currentIndex > testimonials.length - 1){ currentIndex = 0; }}
特地阐明:CSS也是能够实现进度条的。
47. random-image-feed
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:图片布局 + 根本款式布局 +
CSS
提示框的实现(定位 + 伪元素) +CSS
实现回到顶部成果。 - JavaScript:随机数 + (滚动事件的监听)管制回到顶部按钮的显隐。如上述示例局部源码如下:
function onLoad(rows = 5) { container.innerHTML = ""; for (let i = 0; i < rows * 3; i++) { const imageItem = document.createElement("img"); imageItem.src = `${refreshURL}${getRandomSize()}`; imageItem.alt = "random image-" + i; imageItem.loading = "lazy"; container.appendChild(imageItem); }}function getRandomSize() { return `${getRandomValue()}x${getRandomValue()}`;}function getRandomValue() { return Math.floor(Math.random() * 10) + 300;}window.onload = () => { changeBtn.addEventListener("click", () => onLoad()); window.addEventListener("scroll", () => { const { scrollTop, scrollHeight } = document.documentElement || document.body; const { clientHeight } = flexCenter; back.style.display = scrollTop + clientHeight > scrollHeight ? 'block' : 'none'; }) onLoad();}
48. todo-list
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式布局 +
CSS
突变。 - JavaScript:
keydown
与contextmenu
事件的监听 +localStorage API
存储数据。如上述示例局部源码如下:
function addTodo(todo){ let inputValue = input.value; if(todo){ inputValue = todo.text; } if(inputValue){ const liItem = document.createElement("li"); liItem.innerText = inputValue; if(todo && todo.complete){ liItem.classList.add("complete"); } liItem.addEventListener("click",() => { liItem.classList.toggle("complete"); updateList(); }); liItem.addEventListener("contextmenu",(e) => { e.preventDefault(); liItem.remove(); updateList(); }); todoList.appendChild(liItem); input.value = ""; updateList(); }}function updateList(){ const listItem = $$("li",todoList); const saveTodoData = []; listItem.forEach(item => { saveTodoData.push({ text:item.innerText, complete:item.classList.contains("complete") }) }); localStorage.setItem("todoData",JSON.stringify(saveTodoData));}
49. insect-catch-game
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:根本款式布局。
- JavaScript:中英文切换 + 替换元素中的文本(不蕴含标签元素) + 定时器的用法。如上述示例局部源码如下:
function replaceText(el,text,wrapSymbol = ""){ let newText = []; if(wrapSymbol){ // why not use split method?,because it can filter the wrap symbol. const getIndex = (txt) => txt.search(new RegExp("\\" + wrapSymbol)); let searchIndex = getIndex(text),i = 0,len = text.length; while(searchIndex !== -1){ newText.push(text.slice(i,searchIndex) + wrapSymbol); i = searchIndex; if(getIndex(text.slice(searchIndex + 1)) === -1){ newText.push(text.slice(searchIndex + 1,len)); } searchIndex = getIndex(text.slice(searchIndex + 1)); } } const walk = (el,handler) => { const children = Array.from(el.childNodes); let wrapIndex = children.findIndex(node => node.nodeName.toLowerCase() === "br"); children.forEach((node,index) => { if(node.nodeType === 3 && node.textContent.replace(/\s+/,"")){ wrapSymbol ? handler(node,newText[index - wrapIndex < 0 ? 0 : index - wrapIndex]) : handler(node,text);; } }); } walk(el,(node,txt) => { const parent = node.parentNode; parent.insertBefore(document.createTextNode(txt),node); parent.removeChild(node); });}
以上工具函数的实现参考这里来实现的。
特地阐明:这个示例算是一个比拟综合的示例了。
50. kinetic-loader
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:CSS旋转动画 + 根本款式布局。
如上述示例局部源码如下:
@keyframes rotateA { 0%,25% { transform: rotate(0deg); } 50%,75% { transform: rotate(180deg); } 100% { transform: rotate(360deg); }}@keyframes rotateB { 0%,25% { transform: rotate(90deg); } 50%,75% { transform: rotate(270deg); } 100% { transform: rotate(450deg); }}
最初一天,额定的实现了一个404
成果,算是特地结尾吧,是不是很花哨(^_^
)。这算是一个CSS
动画的综合应用,如下所示:
51. 404 page
成果如图所示:
- 源码
- 在线示例
- [ ] 知识点总结:
- CSS:
CSS
动画的用法 + 根本款式布局 +svg
图标元素的款式设置。
如上述示例局部源码如下:
@keyframes background { from { background: linear-gradient(135deg,#e0e0e0 10%,#ffffff 90%); } to { background: linear-gradient(135deg,#ffffff 10%,#e0e0e0 90%); }}@keyframes stampSlide { 0% { transform: rotateX(90deg) rotateZ(-90deg) translateZ(-200px) translateY(130px); } 100% { transform: rotateX(90deg) rotateZ(-90deg) translateZ(-200px) translateY(-4000px); }}@keyframes slide { 0% { transform: translateX(0); } 100% { transform: translateX(-200px); }}@keyframes roll { 0% { transform: rotateZ(0deg); } 85% { transform: rotateZ(90deg); } 87% { transform: rotateZ(88deg); } 90% { transform: rotateZ(90deg); } 100% { transform: rotateZ(90deg); }}@keyframes zeroFour { 0% { content:"4"; } 100% { content:"0"; }}@keyframes draw { 0% { stroke-dasharray: 30 150; stroke-dashoffset: 42; } 100% { stroke:rgba(8, 69, 131, 0.9); stroke-dasharray: 224; stroke-dashoffset: 0; }}