Table of contents
I. Introduction
At present, there 移动端
is 网页端
an indispensable demand for carousels. We have many alternative frameworks or components to implement this function, but it is not as good as we start customizing one ourselves today and 原生js轮播图
summarize and improve relevant knowledge points.
轮播图
It currently appears on the homepages of major shopping websites for display 商品信息
, and many plug-ins are now available to help us achieve a variety of functions more conveniently 轮播图
.
Jingdong
Tmall
Taobao
纯手写轮播图
It may be difficult for beginners, but some companies also use carousel charts to examine interviewees 基础能力
. In fact, the carousel image is relatively simple 模块
as long as it is subdivided into several smaller ones.逐步实现
Below, I will show you how to implement it simply 轮播图
.
2. Animation Basics
We all know that carousel images have an animation process, so how to encapsulate and implement this animation function?
1. Timer
There are two types of timers on the front end, one is a one-time timersetTimeout
and the other is a repetitive timer.setInterval
As shown in the picture above, setTimeout
you only have to click the button before the object will run forward after 15ms 10px
. If setInterval
you only need to click once, it will be executed every 15ms. The countdown effect on the page also does the same.
setInterval
Therefore, we must choose the second option for our carousel chart .
2. left与offsetLeft
left
It is the distance to the left of the positioning object we have added. Here you can refer to some common positioning attributes.
offsetLeft
Is a read-only property ( the value cannot be modifiedoffsetParent
), returning the offset pixel value of the current element relative to the left edge of the node. The current parent node is the entire page, so you only need to assign the offset offsetLeft
to it.object
left
3. Encapsulation function
After we have the timer, we need to consider encapsulating this code into an animation function and just call it when we want.
When encapsulating functions, we must pay attention to parameters. So what parameters should our timer pass in?
物体
目标点
回调函数
3.1 Object
The object is the element we want to move dom
, which is the pink box above that moves on the screen.
3.2 Target point
The movement direction of the box above is there, but once it is executed, it keeps rushing forward, which is not good!
So, let's try to modify the above code. For example, when it arrives, 800px
it will clear the timer and let it stop, otherwise it will continue to move forward. At this time we only need to add a judgment
to the timer .if else
if(object.offsetLeft==500){
clearInterval(timer);
}
else{
object.style.left=object.offsetLeft+10+'px';
}
The target point is met, but there are still two questions?
- How to go back after reaching 800px?
- How to change the motion curve of an object?
Both problems require only one solution, which is to add a step
variable that represents the value of each move instead of a fixed one 10px
.
This variable only needs to be changed to the following formula to calculate:
var step = (target - obj.offsetLeft) / 10;
Our initial motion curve is like this, in a constant speed state:
This formula can not only ensure that the object can retreat, but also satisfy the requirement of first accelerating and then decelerating 曲线运动
.
If you check this formula carefully, css
the distance will actually be biased and smaller than the actual target point. Due to 浮点数
calculation problems, the formula must be used to make approximations.
step = step > 0 ? Math.ceil(step) : Math.floor(step);
3.3 Callback function
回调函数
As the name suggests, when I call this timer function, the target point is reached, the timer is cleared, and the callback function I passed in can be executed.
Next, let the arriving 800px
objects change color.
Of course, you can also achieve special effects later according to your own requirements.
4. Encapsulation
We unify the code written above into one animate.js
file and import it when needed.
function animate(obj, target, callback) {
//排他原理
clearInterval(obj.timer);
obj.timer = setInterval(function () {
//步长
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft == target) {
clearInterval(obj.timer);
//回调函数
callback && callback();
}
else {
obj.style.left = obj.offsetLeft + step + 'px';
}
}, 15);
}
In order to optimize the code and prevent users from excessive clicking, we need to clear the previous timer in advance at the beginning of the timer execution 排他原理
, and then execute our own timer.
3. Basic structure
The structure of building html
a page is actually very simple. We mainly divide it into three parts, namely the middle, the 焦点图
left and right sides 按钮
, and the bottom 小圆点
.
3.1 Focus map
<ul class="rotate-middle">
<li><a href="#"><img src="images/1.jpg" alt=""></a></li>
<li><a href="#"><img src="images/2.jpg" alt=""></a></li>
<li><a href="#"><img src="images/3.jpg" alt=""></a></li>
<li><a href="#"><img src="images/4.jpg" alt=""></a></li>
<li><a href="#"><img src="images/5.jpg" alt=""></a></li>
</ul>
The focus map first defines a 400*300
box at the bottom, and puts pictures one by one in the box. At this time, it should be noted that with each floatli
added , the size of the box also needs to be extended enough to accommodate the size of this row arrangement .ul
图片
3.2 Button
<button class="btn-lt"><</button>
<button class="btn-rt">></button>
I didn't use 字体图标
, 伪元素
or anything like that for the buttons < >
. I just used ordinary ones and just changed the style appropriately.
Extra attention should be paid to adding z-index
a raised position to the button to prevent it from being suppressed by the picture.
3.3 Small dots
<ol class="rotate-bottom">
<li class="current"></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ol>
The bottom is small. 圆点
Now I html
write it directly in it, but later in js
the code it will be updated in real time according to the actual number of pictures.
3.4 Summary
These three basic structures use unified position
positioning ( son and father ), and we ul
also need to add one position: absolute;
because we need to animate the box later.
4. Button display
Our requirement for this part is that 图片
the button will be displayed when the mouse moves to it, but not displayed when it leaves. Before we officially write the code, let’s clarify a question first?
mouseenter
What is the difference between andmouseover
?
Recommended article: Why are mouseenter and mouseover so entangled?
After reading it, choose mouseenter
to avoid bubbling. After obtaining the time source, directly add program execution and use it directly to hide or show the button display
.
focus.addEventListener('mouseenter', function () {
lt.style.display = 'block';
rt.style.display = 'block';
});
focus.addEventListener('mouseleave', function () {
lt.style.display = 'none';
rt.style.display = 'none';
});
5. Dots
5.1 Generate
for (var i = 0; i < ul.children.length; i++) {
//创建ol li
var cloneli = this.document.createElement('li');
ol.appendChild(cloneli);
}
At the beginning, we did html
not give the dots, and later js
generated them in the code based on the number of pictures li
.
5.2 Properties
//自定义属性
ol.children[i].setAttribute('index', i);
In order to better move the carousel images later, we need to ol li
define an attribute for each one index
. Here we are 5
a picture and index
the range is 0~4
.
5.3 Mobile
//绑定事件
ol.children[i].addEventListener('click', function () {
// 排他原理
for (var j = 0; j < ol.children.length; j++) {
ol.children[j].className = '';
}
this.className = 'current';
index = this.getAttribute('index');
num = index;
circle = index;
animate(ul, -fixWidth * index);
})
At this time, every time we click on a dot, we get its current index
value, and then call the animation function to pass 目标值 ul
in the distance - 盒子的大小 * inddex
to move the picture.
6. Button
6.1 Preparation
The movement of the left and right buttons is essentially the same, let's do the right button first. The expected goal is that every time I click 右侧按钮
, the picture will move backward one.
So do we still need to add each picture here 自定义属性
?
In fact, you don’t need to, just customize a variable and adjust it num
according to the number of clicks .++
6.2 Error
As in the picture above, there are several questions:
- The picture moved, but the dots didn’t move?
- When I reach the last picture, how do I go back?
Below, we solve them one by one.
6.2.1 Small dot following
The small dots are easy to follow, we also define a variable circle
, when the button is clicked once, circle++
and then fill the corresponding dot with color.
num
Note that we have to improve the boundary problem here , and we ++
cannot continue when we reach the last picture 归零
.
if (circle == 4) {
circle = 0;
}
else {
circle++;
}
6.2.2 Image return
In fact, when we reach the last picture and click again, it is incoherent and loses the smooth transition effect. 克隆
In fact, we can add the first picture after the last one .
When the picture moves backward, it will transition to the last picture ( that is, the cloned version of the first picture ). At this time, if we click again, we can quickly return to the first picture.
//节点操作,复制照片
var cloneimg = ul.children[0].cloneNode(true);
ul.appendChild(cloneimg);
6.3 bug
As shown in the picture above, we clicked on the dot to reach the third picture, and then clicked the button on the right. It did not return to the fourth picture, so why was it returned to the second picture. This is mainly due to the fact that our ol li
and index
are num cirle
out of sync.
How to improve it is very simple, just index
assign it in real time num cirle
.
For the button on the left, just copy and paste and change a few values. I won’t go into details.
7. Timer
In order to make the carousel move on time, we need to add a timer effect at the end. It is actually very simple. Just call the code of the button on the right directly inside the timer.
var timer = this.setInterval(function () {
rt.click();
}, 1000);
Each time there is an interval of one second, the picture moves one to the right. If the mouse is touched, the carousel of pictures will stop. If the mouse is moved away, the carousel of pictures will continue.
8. Summary
This article mainly implements a simple carousel effect. See you next time!