当青训营遇上码上掘金 | 用原生 JS 实现一个炫酷的名片!

50 阅读3分钟

当青训营遇上码上掘金,想必一定是遇上了吧。

  • 我们是什么!前端工程师!!
  • 我们最喜欢什么!酷!!
  • 我们会干嘛!写代码!!

好了,不玩尬的了(凑字数),今天呢我们就用原生 JS 来实现一个闪亮亮的炫酷名片!效果如下:

建议将预览区放到最大观看

使用到的技术

  • tailwind,本来是懒得写 css 才引入的,后来要用 JS 操作 dom 又不得不写 css 文件,算了,还是能偷点懒。
  • scss,不解释,写样式的。
  • JS 用原生 DOM 操作狂肝!我就不用框架。

对了,这里可以使用码上掘金来引入我们需要的外部依赖,具体操作如下:

image.png

将外链填进去就 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_wrapperinit 类。

代码如下:

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 真是伟大的发明!这次不用,下次一定。