前言
我敢说,这是掘金前无仅有的讲解。关注我,我会颠覆你的认知。
看完后,随便说点关于对本文章的见解,不论是夸赞还是批评。这对作者对于日后更新的文章非常重要🚀
先叠个甲,作者目前才大二,能力有限,各位大佬轻点骂。
对您有帮助的话,不妨帮忙投两票呗
正式讲解
全文大前提,不考虑动画效果
相信90%的前端工作者都写过网页轮播图效果,这在我们网页中是必不可少的。但是我看遍过许多工作了几年的前端工程师写滑块效果。
哦买嘎!说实话我是眼前一黑的😂,多么冗杂的代码😱,令人眼花缭乱的CSS
和JavaScript
。
如果您也是其中的一员,那么本文章绝对对于您来说是个宝藏。
原理
想想我们平常实现轮播图怎么做的?🤔
又是for
循环,又是索引,又是获取一大堆元素,然后给选取的元素添加active
类名实现你想要的效果
我们不妨转化下思维。不是类名添加给物体。而是物体添加给类名。
我们将active
假设为一个容器,第一个元素原本是在容器内的,我们移动第一个元素到最后,其后一个也就是第二个元素进入容器,然后第二个元素移到最后,第三个元素进入容器依次类推。
有点绕口🥵,直接上视频吧
实现
😊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>
页面如图所示
重点来了,利用上面的原理,一行代码解决轮播问题
let slider = document.querySelector('.slider');
let nextBtn = document.getElementById('next');
nextBtn.onClick = () => {
//这里是核心代码,一行解决,其他代码不算数。
slider.append(slider.querySelector('img:first-child'))
}
看!!屌不屌?酷不酷?牛逼不牛逼?🔥🔥🔥
我们来解释下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'))
}
想必我不解释大家也知道是什么意思了。
意思是将
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)
我们可以看到它是直接在末尾加了一个
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)
我们发现此时并没有创建新的元素,而是将第一个li元素移动到了最后
我们也可以通过document.querySelectorAll('*').length
计算页面的DOM
节点数量来证明
没加id
的,可以看到DOM
节点数量是13
加了id
的,可以看到DOM
节点是12
我们也可以去浏览器调试看看,这里不好演示,大家自行去实验即可。
🤔有无缺点
有,缺点在于实现动画效果上极为麻烦(也可能是我水平不到位), 我尝试了不透明度、可见性和过渡,next 项目可以进行过渡,但 prev 项目却不能。
我目前的想法是使用@style-start
的方法,但是它又是个新特性,有兼容性问题
欢迎大佬在评论区提出意见和解决方法。 如果有大佬有解决方法可以在评论区指出,我会万分感谢🙏
总结
酷😎,讲完啦!最后的最后,在评论区告诉我,谁才是掘金的CSS大师😋(开个玩笑😄)!
我们来总结一下我们学到了什么:
-
一行
JavaScript
代码实现轮播图。 -
append
的副作用,当你将一个元素添加(append
)到另一个元素中时,该元素会从它原来的位置被移除并添加到新的位置。 -
要学会思维的转变,这才是最最最重要的。
在我从大一学到大二然后直接进入了一个顶尖的前端特效团队,
我悟出的最好的道理就是——不要不撞南墙不回头!有时候那不是坚持而是倔,事实上生活中遇到的巨石我们只需要绕过去并不需要打碎。
不要忘记评论(这个比较重要),点赞收藏加关注哦~。
如果你有想学习的知识。私信作者或者直接在评论区说出来,作者会根据情况来更新文章的。