仅需一行javaScript代码完成轮播图效果——令你疯狂,令你尖叫,颠覆你认知的JavaScript技巧!🚀

1,680 阅读7分钟

前言

我敢说,这是掘金前无仅有的讲解。关注我,我会颠覆你的认知。

看完后,随便说点关于对本文章的见解,不论是夸赞还是批评。这对作者对于日后更新的文章非常重要🚀

先叠个甲,作者目前才大二,能力有限,各位大佬轻点骂。

对您有帮助的话,不妨帮忙投两票呗 606250606cba56618eb502446bd3d2e.jpg

正式讲解

全文大前提,不考虑动画效果

相信90%的前端工作者都写过网页轮播图效果,这在我们网页中是必不可少的。但是我看遍过许多工作了几年的前端工程师写滑块效果。

哦买嘎!说实话我是眼前一黑的😂,多么冗杂的代码😱,令人眼花缭乱的CSSJavaScript

如果您也是其中的一员,那么本文章绝对对于您来说是个宝藏。

原理

想想我们平常实现轮播图怎么做的?🤔

又是for循环,又是索引,又是获取一大堆元素,然后给选取的元素添加active类名实现你想要的效果

我们不妨转化下思维。不是类名添加给物体。而是物体添加给类名。

我们将active假设为一个容器,第一个元素原本是在容器内的,我们移动第一个元素到最后,其后一个也就是第二个元素进入容器,然后第二个元素移到最后,第三个元素进入容器依次类推。

有点绕口🥵,直接上视频吧

Recording 2024-12-26 012503.gif

实现

😊next操作

那具体代码怎么做呢?请诸君看我的骚操作。😚

我这里准备了三张图片,以及初始化了样式

//隐藏除第一个图片的其他元素
    .slider img:not(:first-child) {
      display: none;
    }
  <div class="banner">
    <div class="slider">
      <img src="../assets/11.jpg">
      <img src="../assets/12.jpg">
      <img src="../assets/13.jpg">
    </div>
    <div class="arrows">
      <button id="prev">prev</button>
      <button id="next">next</button>
    </div>
  </div>

页面如图所示

image.png

重点来了,利用上面的原理,一行代码解决轮播问题

    let slider = document.querySelector('.slider');
    let nextBtn = document.getElementById('next');
    
    nextBtn.onClick = () => {
    //这里是核心代码,一行解决,其他代码不算数。
      slider.append(slider.querySelector('img:first-child'))
    }

Recording 2024-12-26 015119.gif 看!!屌不屌?酷不酷?牛逼不牛逼?🔥🔥🔥

我们来解释下slider.append(slider.querySelector('img:first-child'))这段代码的意思。

img:first-child'是一个CSS选择器,它的意思是选择 slider 元素下的第一个 img 子元素,也就是我们第一个图片,所以slider.querySelector('img:first-child'))这段代码意思就很明显了,意思是选择slider 元素内的第一个 img 子元素。

那么slider.append(slider.querySelector('img:first-child'))这段代码的意思也呼之欲出😄,意思是将slider 元素内的第一个 img 子元素从其当前位置移动到 slider 元素内子元素列表的末尾。

😍prev操作

同理,我们也可以进行prev操作,一样一行代码解决

    let prevBtn = document.getElementById('prev');
    prevBtn.onclick = () => {
      slider.prepend(slider.querySelector('img:last-child'))
    }

Recording 2024-12-26 020325.gif 想必我不解释大家也知道是什么意思了。 意思是将slider 元素中的最后一个 img 子元素从其当前位置移动到 slider 元素内子元素列表的开头。

上面的内容是不是已经很炸裂了?集中注意力!接下来我要说的东西可能会颠覆你的认知

🤩颠覆你认知的append

在上面的例子中,可能会有大佬想,我们并没有进行删除节点的操作,那么我们一直点岂不是会制造出大量的节点导致浏览器卡顿。

告诉你!这种方法不会。

事实上append 或 prepend 等方法操作 DOM元素时,会产生有趣的副作用: 以 append 方法为例,当你将一个元素添加(append)到另一个元素中时,该元素会从它原来的位置被移除并添加到新的位置。 这是因为在 DOM 树中,一个元素节点只能存在于一个父节点的子节点列表中。

例如,如果有元素 A 在父元素 P1 的子元素列表中,当你将 A 追加(append)到另一个父元素 P2 时,它会从 P1 的子元素列表中被移除,从而产生一种元素 “移动” 的效果。

这是由于 DOM 树的这种层次结构特性所导致的,确保元素的唯一性和树结构的完整性。

👀证明

口说无凭,毛爷爷说过:实践出真理!

我们这里准备了了三个列表

  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
  </ul>
    let ul = document.querySelector('ul');
    let li = document.createElement('li');
    ul.append(li)

image.png 我们可以看到它是直接在末尾加了一个li元素。

如果我们给li加上id,并且使用document.getElementById选中它

  <ul>
    <li id="first">1</li>
    <li>2</li>
    <li>3</li>
  </ul>
    let ul = document.querySelector('ul');
    let li = document.getElementById('first');
    ul.append(li)

image.png 我们发现此时并没有创建新的元素,而是将第一个li元素移动到了最后

我们也可以通过document.querySelectorAll('*').length计算页面的DOM节点数量来证明

没加id的,可以看到DOM节点数量是13

image.png

加了id的,可以看到DOM节点是12

image.png 我们也可以去浏览器调试看看,这里不好演示,大家自行去实验即可。

🤔有无缺点

有,缺点在于实现动画效果上极为麻烦(也可能是我水平不到位), 我尝试了不透明度、可见性和过渡,next 项目可以进行过渡,但 prev 项目却不能。

我目前的想法是使用@style-start的方法,但是它又是个新特性,有兼容性问题

欢迎大佬在评论区提出意见和解决方法。 如果有大佬有解决方法可以在评论区指出,我会万分感谢🙏

总结

酷😎,讲完啦!最后的最后,在评论区告诉我,谁才是掘金的CSS大师😋(开个玩笑😄)!

我们来总结一下我们学到了什么:

  • 一行JavaScript代码实现轮播图。

  • append的副作用,当你将一个元素添加(append)到另一个元素中时,该元素会从它原来的位置被移除并添加到新的位置。

  • 要学会思维的转变,这才是最最最重要的。

在我从大一学到大二然后直接进入了一个顶尖的前端特效团队,

我悟出的最好的道理就是——不要不撞南墙不回头!有时候那不是坚持而是倔,事实上生活中遇到的巨石我们只需要绕过去并不需要打碎。

不要忘记评论(这个比较重要),点赞收藏加关注哦~。

如果你有想学习的知识。私信作者或者直接在评论区说出来,作者会根据情况来更新文章的。