当青训营遇上码上掘金,想必一定是遇上了吧。
- 我们是什么!前端工程师!!
- 我们最喜欢什么!酷!!
- 我们会干嘛!写代码!!
好了,不玩尬的了(凑字数),今天呢我们就用原生 JS 来实现一个闪亮亮的炫酷名片!效果如下:
建议将预览区放到最大观看
使用到的技术
tailwind
,本来是懒得写 css 才引入的,后来要用 JS 操作 dom 又不得不写 css 文件,算了,还是能偷点懒。scss
,不解释,写样式的。JS
用原生 DOM 操作狂肝!我就不用框架。
对了,这里可以使用码上掘金来引入我们需要的外部依赖,具体操作如下:
将外链填进去就 OK,为码上掘金点赞😀。
内层导航栏实现
外面的东西没啥好讲的,主要是弹出的动画和导航栏动画。
首先为页面中的导航标签设置事件监听器。通过遍历 navTabs,为每个导航标签设置一个点击事件处理函数。当某个导航标签被点击时,该处理函数执行以下操作:
-
获取当前点击的标签的位置索引(eq),并使用该索引创建 "ripple" 和 "mega-ripple" 类的 HTML 元素。
-
将 "ripple" 元素添加到当前点击的标签上,并在一秒钟后删除该元素。
-
将 "mega-ripple" 元素添加到文档中的 "content" 元素上,并在一秒钟后删除该元素。
-
将当前点击的标签设置为 "active" 状态,并删除文档中的其他 "active" 标签。
-
设置与当前点击的标签相对应的卡片为 "active" 状态,并删除文档中的其他 "active" 卡片。
-
设置与当前点击的标签相对应的内容部分为 "active" 状态,并删除文档中的其他 "active" 内容部分。
这就简单的实现了导航的切换效果,代码如下:
navTabs.forEach(tab => {
tab.addEventListener("click", function (e) {
const eq = Array.from(navTabs).indexOf(this);
const ripple = document.createElement("div");
ripple.classList.add("ripple");
ripple.style.left = `${e.clientX - this.offsetLeft}px`;
ripple.style.top = `${e.clientY - this.offsetTop}px`;
this.appendChild(ripple);
setTimeout(() => {
ripple.remove();
}, 1000);
const megaRipple = document.createElement("div");
megaRipple.classList.add("ripple");
megaRipple.classList.add("mega");
megaRipple.style.left = `${e.clientX}px`;
megaRipple.style.top = `${e.clientY}px`;
megaRipple.style.background = window
.getComputedStyle(this)
.getPropertyValue("border-color");
document.querySelector("#content_wrapper > div.content").appendChild(
megaRipple
);
setTimeout(() => {
megaRipple.style.opacity = 0;
setTimeout(() => {
megaRipple.remove();
}, 1000);
}, 500);
document.querySelector("nav.main .active").classList.remove("active");
this.classList.add("active");
document.querySelectorAll("#grid_wrapper > card > div").forEach(div => {
div.classList.remove("active");
});
const card = document.querySelectorAll("#grid_wrapper > card")[eq].querySelector("div");
document.querySelector("#content_wrapper > div.clone > span").innerHTML = card.querySelector("span").innerHTML;
card.classList.add("active");
document.querySelectorAll("#content_wrapper > div.content > section").forEach(section => {
section.classList.remove("active");
});
document.querySelectorAll("#content_wrapper > div.content > section")[eq].classList.add("active");
});
});
导航过渡效果
点击导航时,有一个好看的过渡效果,它可以通过 delay
来实现:
首先通过 document.querySelectorAll("nav.main > .tab")
获取页面中所有的导航标签元素,并将其保存在变量 navTabs
中。然后使用 forEach
遍历所有导航标签元素,并设置该元素的过渡效果延迟,具体延迟时间为 index * 0.05
秒,其中 index
是遍历到的元素在集合中的下标。
此外,卡片的过渡效果延迟实现也很类似。首先通过 document.querySelectorAll("#grid_wrapper > card")
获取页面中所有的卡片元素,并将其保存在变量 cards
中。然后使用 forEach
遍历所有卡片元素,并设置该元素的过渡效果延迟,具体延迟时间为 index * 0.05
秒。
最后,通过监听页面的 DOMContentLoaded
事件,在页面加载完成后移除页面元素 #grid_wrapper
的 init
类。
代码如下:
const navTabs = document.querySelectorAll("nav.main > .tab");
navTabs.forEach((tab, index) => {
tab.style.transitionDelay = `${index * 0.05}s`;
});
const cards = document.querySelectorAll("#grid_wrapper > card");
cards.forEach((card, index) => {
card.style.transitionDelay = `${index * 0.05}s`;
});
document.addEventListener("DOMContentLoaded", function () {
document.querySelector("#grid_wrapper").classList.remove("init");
});
其他的样式以及细枝末节的实现,可以参考源代码,这里就不再赘述了。
碎碎念
最后容我说一句:jQuery 真是伟大的发明!这次不用,下次一定。