点击上方 前端瓶子君,关注公众号

回复算法,加入前端编程面试算法每日一题群

所有示例源码地址:https://github.com/eveningwater/my-web-projects/tree/master/js

1.Expanding Cards

效果如图所示:

1.png
  • 源码[1]

  • 在线示例[2]

  • [ ] 知识点总结:

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

效果如图所示:

2.gif
  • 源码[3]

  • 在线示例[4]

  • [ ] 知识点总结:

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

效果如图所示:

3.gif
  • 源码[5]

  • 在线示例[6]

  • [ ] 知识点总结:

CSS:CSS弹性盒子布局加rotate动画。

JavaScript:添加和移除类名的操作。如上述示例部分源码如下:

const addClass = (el,className) => el.classList.add(className);
const removeClass = (el,className) => el.classList.remove(className);
复制代码

4.hidden-search-widget

效果如图所示:

4.gif
  • 源码[7]

  • 在线示例[8]

  • [ ] 知识点总结:

CSS:CSS过渡动画 + 宽度的更改 + inputplaceholder样式。

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

效果如图所示:

5.gif
  • 源码[9]

  • 在线示例[10]

  • [ ] 知识点总结:

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之间。详情[11]

6.Scroll Animation

效果如图所示:

6.gif
  • 源码[12]

  • 在线示例[13]

  • [ ] 知识点总结:

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

效果如图所示:

7.gif
  • 源码[14]

  • 在线示例[15]

  • [ ] 知识点总结:

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、mouseleavemouseover、mouseout的区别,总结如下:

  1. enter只触发1次,只有等到鼠标离开了目标元素之后再进入才会继续触发,同理leave也是如此理解。而over与out就是不断的触发。

  2. enter进入子元素,通过e.target也无法区分是移入/移出子元素还是父元素,而over与out则可以区分。

8.Form Wave

效果如图所示:

8.gif
  • 源码[16]

  • 在线示例[17]

  • [ ] 知识点总结:

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

效果如图所示:

9.gif
  • 源码[18]

  • 在线示例[19]

  • [ ] 知识点总结:

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

效果如图所示:

10.gif
  • 源码[20]

  • 在线示例[21]

  • [ ] 知识点总结:

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

效果如图所示:

11.gif
  • 源码[22]

  • 在线示例[23]

  • [ ] 知识点总结:

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

效果如图所示:

12.gif
  • 源码[24]

  • 在线示例[25]

  • [ ] 知识点总结:

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

效果如图所示:

13.gif
  • 源码[26]

  • 在线示例[27]

  • [ ] 知识点总结:

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

效果如图所示:

14.gif
  • 源码[28]

  • 在线示例[29]

  • [ ] 知识点总结:

CSS:基本样式 + 定位 + 位移变换以及角度旋转。

JavaScript:类名的切换。如上述示例部分源码如下:

toggle.addEventListener('click',() => nav.classList.toggle('active'));
复制代码

15. Incrementing Counter

效果如图所示:

15.gif
  • 源码[30]

  • 在线示例[31]

  • [ ] 知识点总结:

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

效果如图所示:

16.gif
  • 源码[32]

  • 在线示例[33]

  • [ ] 知识点总结:

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

效果如图所示:

17.gif
  • 源码[34]

  • 在线示例[35]

  • [ ] 知识点总结:

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

效果如图所示:

18.gif
  • 源码[36]

  • 在线示例[37]

  • [ ] 知识点总结:

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

效果如图所示:

19.gif
  • 源码[38]

  • 在线示例[39]

  • [ ] 知识点总结:

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 }&nbsp;${ 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

效果如图所示:

20.gif
  • 源码[40]

  • 在线示例[41]

  • [ ] 知识点总结:

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

效果如图所示:

21.gif
  • 源码[42]

  • 在线示例[43]

  • [ ] 知识点总结:

CSS:基本样式。

JavaScript:canvas API + mouse事件以及计算xy坐标 + 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

效果如图所示:

22.png
  • 源码[44]

  • 在线示例[45]

  • [ ] 知识点总结:

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

效果如图所示:

23.gif
  • 源码[46]

  • 在线示例[47]

  • [ ] 知识点总结:

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

效果如图所示:

24.gif
  • 源码[48]

  • 在线示例[49]

  • [ ] 知识点总结:

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

效果如图所示:

25.gif
  • 源码[50]

  • 在线示例[51]

  • [ ] 知识点总结:

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

效果如图所示:

26.gif
  • 源码[52]

  • 在线示例[53]

  • [ ] 知识点总结:

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 = "&times;";closeIte.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();});}}
复制代码

消息提示框实现思路可以参考这篇文章[54]

27. github-profiles

效果如图所示:

27.gif
  • 源码[55]

  • 在线示例[56]

  • [ ] 知识点总结:

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

效果如图所示:

28.gif
  • 源码[57]

  • 在线示例[58]

  • [ ] 知识点总结:

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

效果如图所示:

29.gif
  • 源码[59]

  • 在线示例[60]

  • [ ] 知识点总结:

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

效果如图所示:

30.gif
  • 源码[61]

  • 在线示例[62]

  • [ ] 知识点总结:

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

效果如图所示:

31.gif
  • 源码[63]

  • 在线示例[64]

  • [ ] 知识点总结:

CSS:CSS实现开关小组件样式 + 基本布局样式。

JavaScript:inputchange事件的监听。如上述示例部分源码如下:

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

效果如图所示:

32.gif
  • 源码[65]

  • 在线示例[66]

  • [ ] 知识点总结:

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

效果如图所示:

33.gif
  • 源码[67]

  • 在线示例[68]

  • [ ] 知识点总结:

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

效果如图所示:

34.png
  • 源码[69]

  • 在线示例[70]

  • [ ] 知识点总结:

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的延迟执行。参考规范[71]

35. hover board

效果如图所示:

35.gif
  • 源码[72]

  • 在线示例[73]

  • [ ] 知识点总结:

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

效果如图所示:

36.gif
  • 源码[74]

  • 在线示例[75]

  • [ ] 知识点总结:

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

效果如图所示:

37.gif
  • 源码[76]

  • 在线示例[77]

  • [ ] 知识点总结:

CSS:基本样式布局 + CSS渐变实现手机布局。2. 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

效果如图所示:

38.gif
  • 源码[78]

  • 在线示例[79]

  • [ ] 知识点总结:

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

效果如图所示:

39.gif
  • 源码[80]

  • 在线示例[81]

  • [ ] 知识点总结:

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

效果如图所示:

40.gif
  • 源码[82]

  • 在线示例[83]

  • [ ] 知识点总结:

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

效果如图所示:

41.gif
  • 源码[84]

  • 在线示例[85]

  • [ ] 知识点总结:

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

效果如图所示:

42.gif
  • 源码[86]

  • 在线示例[87]

  • [ ] 知识点总结:

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

效果如图所示:

43.gif
  • 源码[88]

  • 在线示例[89]

  • [ ] 知识点总结:

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 numberconst value = +e.target.value;const label = e.target.nextElementSibling;const range_width = getStyle(e.target,"width");//XXpxconst label_width = getStyle(label,"width");//XXpx// Due to contain px,slice the widthconst 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

效果如图所示:

44.gif
  • 源码[90]

  • 在线示例[91]

  • [ ] 知识点总结:

CSS:导航宽度的变化 + CSS渐变 + 基本样式布局。

JavaScript:点击按钮切换导航栏的显隐。如上述示例部分源码如下:

function changeNav(type){navList.forEach(nav => nav.classList[type === "open" ? "add" : "remove"]("visible"));
}
复制代码

45. quiz-app

效果如图所示:

45.gif
  • 源码[92]

  • 在线示例[93]

  • [ ] 知识点总结:

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

效果如图所示:

46.gif
  • 源码[94]

  • 在线示例[95]

  • [ ] 知识点总结:

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

效果如图所示:

47.gif
  • 源码[96]

  • 在线示例[97]

  • [ ] 知识点总结:

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

效果如图所示:

48.gif
  • 源码[98]

  • 在线示例[99]

  • [ ] 知识点总结:

CSS:基本样式布局 + CSS渐变。

JavaScript:keydowncontextmenu事件的监听 + 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

效果如图所示:

49.gif
  • 源码[100]

  • 在线示例[101]

  • [ ] 知识点总结:

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);});
}
复制代码

以上工具函数的实现参考这里来实现的[102]

特别说明:这个示例算是一个比较综合的示例了。

50. kinetic-loader

效果如图所示:

50.gif
  • 源码[103]

  • 在线示例[104]

  • [ ] 知识点总结:

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

效果如图所示:

51.gif

  • 源码[105]

  • 在线示例[106]

  • [ ] 知识点总结:

  1. 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;}
}
复制代码

关于本文

来源:夕水

https://segmentfault.com/a/1190000040481518

最后

欢迎关注【前端瓶子君】✿✿ヽ(°▽°)ノ✿

回复「算法」,加入前端编程源码算法群,每日一道面试题(工作日),第二天瓶子君都会很认真的解答哟!

回复「交流」,吹吹水、聊聊技术、吐吐槽!

回复「阅读」,每日刷刷高质量好文!

如果这篇文章对你有帮助,「在看」是最大的支持

》》面试官也在看的算法资料《《

“在看和转发”就是最大的支持

50天用JavaScript完成50个web项目,我学到了什么?相关推荐

  1. 【案例练习】12—50 个从今天就可以开始做起来的小型Web项目

    英文 | https://50projects50days.com/ 整理 | 杨小爱 "从未开始的工作需要最长时间才能完成." - J.R.R. 托尔金 我们经常被告知要么做大, ...

  2. 了不起的Node.js: 将JavaScript进行到底(Web开发首选,实时,跨多服务器,高并发)...

    了不起的Node.js: 将JavaScript进行到底(Web开发首选,实时,跨多服务器,高并发) Guillermo Rauch 编   赵静 译 ISBN 978-7-121-21769-2 2 ...

  3. GitHub上50个最受欢迎的PHP开源项目【2019】

    2019年过去一大半了,PHP中文网为你总结整理下GitHub上在2019年都有哪些流行的PHP相关开源项目,以下是按照GitHub Stars排序的,欢迎参考! GitHub上50个最受欢迎的PHP ...

  4. Python|Git remote|hosts|PyCharm常用快捷键|变量转换|命名|类型|运算符|分支|调整tab|循环|语言基础50课:学习记录(1)-项目简介及变量、条件及循环

    目录 系列目录 均引自原项目地址: Python语言基础50课简介及相关网址 修改 hosts 文件 解决 GitHub 上图片无法显示 视频资源 Python语言基础50课代码等文件资源 表1. P ...

  5. 有了 Docker,用 JavaScript 框架开发的 Web 站点也能很好地支持网络爬虫的内容抓取...

    点这里 阅读目录 用 AngularJS(以及其它 JavaScript 框架)开发的 Web 站点不支持爬虫的抓取 解决方案 为什么公开我们的解决方案 实现 AngularJS 服务 结论   Pr ...

  6. 9 个基于JavaScript 和 CSS 的 Web 图表框架

    jQuery, MooTools, Prototype 等优秀的 JavaScript 框架拥有各种强大的功能,包括绘制 Web 图表,使用这些框架以及相应插件,我们可以非常轻松地实现曲线图,圆饼图, ...

  7. Javascript 操作 SharePoint media web part

    本文讲述如何用Javascript 操作 SharePoint media web part. 需求是这样的,SharePoint页面上所有若干链接到Media文件(wmv;wma;avi;mpg;m ...

  8. 20180925_Python练习题-三:一个商场在降价促销。如果购买金额50~100元(包含50元和100元)之间,会给10%的折扣;如果购买金额大于100元,会給20%折扣。编写一程序,询问购买价

    # 一个商场在降价促销.如果购买金额50~100元(包含50元和100元)之间,会给10%的折扣:如果购买金额大于100元,会給20%折扣.编写一程序,询问购买价 # 格,再显示出折扣(10%或20% ...

  9. 如何在React工程中使用JavaScript Barcode SDK创建Web条形码应用

    基于WebAssembly构建的Dynamsoft JavaScript Barcode SDK让Web开发者能够创建适用于浏览器的高性能条码应用.这篇文章分享下如何使用React快速创建一个简单的W ...

最新文章

  1. 光大银行分布式实战:国内最大缴费平台的数据库架构转型
  2. weblogic修改java重启_修改weblogic域的jdk
  3. leetcode算法题--掷骰子模拟★★
  4. Ubuntu 19.10 发布 | 云原生生态周报 Vol. 24
  5. java 二维高斯_Java Random nextGaussian()用法及代码示例
  6. 计算机gt的使用方法,旗舰级综合效果器 BOSS GT-1000使用宝典(二) | 基础操作
  7. 搜索 —— 启发式搜索 —— 模拟退火
  8. java面试排序_Java-四种面试常考排序
  9. Linux学习笔记013---CentOs7中vsftpd的安装和卸载
  10. 面向对象的tab选项卡实现
  11. Kylin 2.0 Spark Cubing 优化改进
  12. pandas读取csv文件数据并对指定字段分类使用matplotlib在一张图里画四张折线图子图
  13. springboot项目去除druid监控的广告超链接等
  14. 数据结构-顺序表基本操作的实现(含全部代码)
  15. python股票量化交易_量化交易之路:用Python做股票量化分析 (阿布著) 完整pdf扫描版[103MB]...
  16. CSMACA 与 CSMA/CD 区别
  17. Nodejs:ESModule和commonjs,傻傻分不清
  18. OmniPeek-20180725-Error 2502/Error 2053
  19. 基于C#弹幕类射击游戏的实现——(五)主场景
  20. iphone11夜景鬼影分析

热门文章

  1. P1134 高精度阶乘
  2. R语言将文件写入CSV,并读取
  3. oracle如何设置连接数,关于Oracle连接数设置
  4. 3-动态规划:数字三角形
  5. Blender 画正四面体
  6. 通信手机术语:什么是IMEI IMEI串号组成
  7. 自如_智能家居硬件测试
  8. 梅西:世界杯是我最重要的奖杯;很高兴斯卡洛尼能够续约
  9. 酒馆指南:小白开店必备
  10. 2019年:两成开发者月薪超1.7万,算法工程师最紧缺