Home > Web Front-end > JS Tutorial > How to implement a carousel using native JavaScript? Detailed code explanation

How to implement a carousel using native JavaScript? Detailed code explanation

php是最好的语言
Release: 2018-08-07 10:58:27
Original
3152 people have browsed it

Implementation principle

How to implement a carousel using native JavaScript? Detailed code explanation

Use a custom animate function to change the left value of the element so that the image scrolls left and right Effect

HTML:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <link rel="stylesheet" type="text/css" href="StyleSheet.css">
    <title></title>
</head>
<body>
    <p id="scroll" class="scroll">
        <p id="box" class="box">
            <ul id="ul" style="left:-950px;">
                <li><img  src="images/top_banner_bw01.jpg"    style="max-width:90%"  style="max-width:90%" alt="How to implement a carousel using native JavaScript? Detailed code explanation" ></li>
                <li><img  src="images/top_banner_bw02.jpg"    style="max-width:90%"  style="max-width:90%" alt="How to implement a carousel using native JavaScript? Detailed code explanation" ></li>
                <li><img  src="images/top_banner_bw03.jpg"    style="max-width:90%"  style="max-width:90%" alt="How to implement a carousel using native JavaScript? Detailed code explanation" ></li>
                <li><img  src="images/top_banner_bw04.jpg"    style="max-width:90%"  style="max-width:90%" alt="How to implement a carousel using native JavaScript? Detailed code explanation" ></li>
                <li><img  src="images/top_banner_bw05.jpg"    style="max-width:90%"  style="max-width:90%" alt="How to implement a carousel using native JavaScript? Detailed code explanation" ></li>
            </ul>
            <ol id="olnavi"></ol>
        </p>
        <p id="last"></p>
        <p id="next"></p>
    </p>
    <script src="a.js"></script>
</body>
</html>
Copy after login

CSS:

body, p, p,
h1, h2, h3, h4, h5, h6,
dl, dt, dd, ul, ol, li,
table, caption, th, td,
form, fieldset, input, textarea, select,
pre, address, blockquote,
embed, object {
    margin: 0px;
    padding: 0px;
}

ul, ol {
    list-style:none;
}

img {
    vertical-align: top;
}

.scroll {
    width: 950px;
    height: 438px;
    margin: auto;
    overflow: hidden;
    position: relative;
}

.box {
    width: 950px;
    height: 438px;
    overflow: hidden;
    position: relative;
}

.box ul{
    width: 700%;
    position: absolute;
    left: 0;
    top: 0;
    padding:0px;
    margin:0px;
}

.box ul li{
    float: left;
}

.scroll ol {
    position: absolute;
    right: 365px;
    bottom: 5px;
}

.scroll ol li {
    float: left;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: #000;
    margin-left: 10px;
    cursor: pointer;
    opacity: 0.5;
}

.scroll ol li.current {
    background-color: #000099;
    opacity: 0.8;
}

#last {
    position: absolute;
    bottom: 179px;
    width: 80px;
    height: 80px;
    cursor: pointer;
}

#next {
    position: absolute;
    bottom: 179px;
    right: 0px;
    width: 80px;
    height: 80px;
    cursor: pointer;
}
Copy after login

How to implement a carousel using native JavaScript? Detailed code explanation

The display effect is as shown above

Next, we will explain the js code, First get the elements in html

var scroll = document.getElementById("scroll");
var ul = document.getElementById("ul");
var ulLis = ul.children;
var liWidth = ul.children[0].offsetWidth;
Copy after login


Before that, we need to understand that the small dots are not hard-coded, they are determined based on the number of pictures in ul li.

var ol = document.getElementById("olnavi");
for (var i = 0; i < ulLis.length - 2; i++) {
    var li = document.createElement("li");
    li.id = (i + 1);  //id用于后面为li添加事件
    ol.appendChild(li);
    
}
ol.children[0].className = "current" //将第一个小圆点设置为触发状态
Copy after login

To achieve seamless scrolling, you need two more pictures, that is, clone the first picture and put it behind the last one, clone the last picture and put it in front of the first picture.

var num = ulLis.length - 1;
ul.appendChild(ul.children[0].cloneNode(true));
ul.insertBefore(ul.children[num].cloneNode(true), ul.firstChild);
Copy after login

Next, add events for the left and right arrows. When the mouse is placed on the arrows, the color will change.

var last = document.getElementById("last");
last.style.background = "url(images/last-control.png)";

last.addEventListener("mouseenter", function () {
    last.style.background = "url(images/newlast-control.png)";
}, false);

last.addEventListener("mouseleave", function () {
    last.style.background = "url(images/last-control.png)";
}, false);

var next = document.getElementById("next");
next.style.background = "url(images/next-control.png)";

next.addEventListener("mouseenter", function () {
    next.style.background = "url(images/newnext-control.png)";
}, false);

next.addEventListener("mouseleave", function () {
    next.style.background = "url(images/next-control.png)";
}, false);
Copy after login

We then use js to animate the animation. The animation part includes:
1. How many hours are the mouse clicked? Dots, which picture will be displayed, and the color of the small dots will also change.
2. Click the left and right arrows with the mouse, and the picture will move to the left and right
3. The pictures will automatically rotate, (this requires A timer)
4. When the mouse is placed on the picture, the picture will stop playing automatically (this requires clearing the timer)
5. When the mouse leaves the picture, the picture will continue to rotate automatically (restart the timer)
Here We encapsulate an animate() animation function

function animate(obj, target) {  //obj为需要移动的元素,在本文中为ul,target为需要移动到的位置
    var speed = obj.offsetLeft < target ? 10 : -10;  //判断速度向左还是向右
    obj.timer = setInterval(function () {  //计时器每隔一定时间移动一次
        var result = target - obj.offsetLeft;  //剩余需要移动的距离
        obj.style.left = obj.offsetLeft + speed + "px";  //改变元素的left来实现移动          
        if (Math.abs(result) <= Math.abs(speed)) {  //当需要移动的距离小于速度时
            clearInterval(obj.timer);   //清除计时器
            obj.style.left = target + "px";  //直接移动到需要移动的位置
            flag = true;  //将flag置为true,使点击事件能再次触发
        }
    }, 1);
}
Copy after login

Next, assign the animation function to the left and right arrows

var flag = true;  //用于判断上一个事件是否执行完毕,如果没有执行完毕禁止再次触发事件
var index = 1;  //是第几个小圆点
var lastclick = function () {
    if (flag) {
        flag = false;  //进入事件将flag置为false
        console.log(flag);
        if (index === 1) {  //判断是否为第一张
            index = 6;
            ul.style.left = "-5700px";  //当移动到第一张时,再向右移前会替换到最后一张后面的第一张,然后再向右移动。
            animate(ul, ul.offsetLeft + liWidth); //动画函数一次向有移动一个图片长度的距离
        }
        else {
            animate(ul, ul.offsetLeft + liWidth);
        }
        index -= 1; //移动小圆点计数器
        btnShow(index);  //给新的小圆点高亮,取消上一个小圆点的高亮
    }
}
last.addEventListener("click", lastclick, false);  //将函数赋给点击事件

var nextclick = function () {  //向左移与向右移类似
    if (flag) {
        flag = false;
        if (index === 5) {
            index = 0;
            ul.style.left = "0px";
            animate(ul, ul.offsetLeft - liWidth);
        }
        else {
            animate(ul, ul.offsetLeft - liWidth);
        }
        index += 1;
        btnShow(index);
    }
}
next.addEventListener("click",nextclick, false);

function btnShow(cur_index) {
    for (var i = 0; i < ol.children.length; i++) {
        ol.children[i].className = &#39; &#39;; //取消全部li的类
    }
    ol.children[cur_index - 1].className = "current";  //给新的小圆点加上类
}
Copy after login

Plus a timer, the next picture will be triggered every once in a while To achieve the effect of carousel

var timer;
function play() {
    timer = setInterval(nextclick, 3000)
}

scroll.addEventListener("load", play(), false);  //整个p全部加载完毕后开始

scroll.addEventListener("mouseenter", function () { //鼠标移入图片是清除计时器
    clearInterval(timer);
}, false);

scroll.addEventListener("mouseleave", function () {  //鼠标移出图片时再次启动计时器
    play();
}, false);
Copy after login

Finally add events to the small dots, click on which carousel to which picture

//小圆点的点击事件
var olliclick = function () {
    if (flag) {
        flag = false;
        var cur_li = document.getElementsByClassName("current");
        var lastid = cur_li[0].id;  //当前的小圆点是第几个
        var distance = this.id - lastid;  //计算当前小圆点与点击的小圆点的距离(分正负)
        if (distance == 0) {
            flag = true;
        }
        else {
            animate_ol(ul, distance);
        }
    }
}

//给所有的小圆点添加上点击事件
var ollitimer = 1
var lis = ol.getElementsByTagName(&#39;li&#39;);
for (ollitimer; ollitimer < lis.length+1; ollitimer++) {
    var olli = document.getElementById(ollitimer);
    olli.addEventListener("click", olliclick, false);
}

function animate_ol(obj, value) {  //小圆点动画函数
    if (value > 0) {  //判断移动方向
        var speed = -20*value; //使动画时间一致
    }
    if (value < 0) {
        var speed = -20*value;
    }
    var lastleft = obj.offsetLeft;
    obj.timer = setInterval(function () {
        var distance = Math.abs(value * liWidth) - Math.abs(obj.offsetLeft - lastleft);
        //剩余需要移动的距离
        if (distance < Math.abs(speed)) {
            clearInterval(obj.timer);
            if (value > 0) {
                obj.style.left = obj.offsetLeft - distance + "px";
                flag = true;
            }
            if (value < 0) {
                obj.style.left = obj.offsetLeft + distance + "px";
                flag = true;
            }
        }
        else {
            obj.style.left = obj.offsetLeft + speed + "px";
        }
    }, 1);
    index = index + value;
    btnShow(index);
}
Copy after login

And then summarize the common ghost bugs :
Prevent timer conflicts caused by multiple clicks by setting the flag. After clicking, set the flag to false, and then set it to true at the end of the animation function. This will only happen after the previous click event animation ends. Triggered a second time.

Finally put the complete js code

var scroll = document.getElementById("scroll");
var ul = document.getElementById("ul");
var ulLis = ul.children;
var liWidth = ul.children[0].offsetWidth;

var num = ulLis.length - 1;
ul.appendChild(ul.children[0].cloneNode(true));
ul.insertBefore(ul.children[num].cloneNode(true), ul.firstChild);

var ol = document.getElementById("olnavi");
for (var i = 0; i < ulLis.length - 2; i++) {
    var li = document.createElement("li");
    li.id = (i + 1);
    ol.appendChild(li);
    
}
ol.children[0].className = "current";

var last = document.getElementById("last");
last.style.background = "url(images/last-control.png)";

last.addEventListener("mouseenter", function () {
    last.style.background = "url(images/newlast-control.png)";
}, false);

last.addEventListener("mouseleave", function () {
    last.style.background = "url(images/last-control.png)";
}, false);

var next = document.getElementById("next");
next.style.background = "url(images/next-control.png)";

next.addEventListener("mouseenter", function () {
    next.style.background = "url(images/newnext-control.png)";
}, false);

next.addEventListener("mouseleave", function () {
    next.style.background = "url(images/next-control.png)";
}, false);

var flag = true;
var index = 1;
var lastclick = function () {
    if (flag) {
        flag = false;
        console.log(flag);
        if (index === 1) {
            index = 6;
            ul.style.left = "-5700px";
            animate(ul, ul.offsetLeft + liWidth);
        }
        else {
            animate(ul, ul.offsetLeft + liWidth);
        }
        index -= 1;
        btnShow(index);
    }
}
last.addEventListener("click", lastclick, false);

var nextclick = function () {
    if (flag) {
        flag = false;
        if (index === 5) {
            index = 0;
            ul.style.left = "0px";
            animate(ul, ul.offsetLeft - liWidth);
        }
        else {
            animate(ul, ul.offsetLeft - liWidth);
        }
        index += 1;
        btnShow(index);
    }
}
next.addEventListener("click",nextclick, false);

function btnShow(cur_index) {
    for (var i = 0; i < ol.children.length; i++) {
        ol.children[i].className = ' ';
    }
    ol.children[cur_index - 1].className = "current";
}

function animate(obj, target) {
    var speed = obj.offsetLeft < target ? 10 : -10;
    obj.timer = setInterval(function () {
        var result = target - obj.offsetLeft;
        obj.style.left = obj.offsetLeft + speed + "px";            
        if (Math.abs(result) <= Math.abs(speed)) {
            clearInterval(obj.timer);
            obj.style.left = target + "px";
            flag = true;
        }
    }, 1);
}

var timer;
function play() {
    timer = setInterval(nextclick, 3000)
}

scroll.addEventListener("load", play(), false);

scroll.addEventListener("mouseenter", function () {
    clearInterval(timer);
}, false);

scroll.addEventListener("mouseleave", function () {
    play();
}, false);

var olliclick = function () {
    if (flag) {
        flag = false;
        var cur_li = document.getElementsByClassName("current");
        var lastid = cur_li[0].id;
        var distance = this.id - lastid;
        if (distance == 0) {
            flag = true;
        }
        else {
            animate_ol(ul, distance);
        }
    }
}
var ollitimer = 1
var lis = ol.getElementsByTagName('li');
for (ollitimer; ollitimer < lis.length+1; ollitimer++) {
    var olli = document.getElementById(ollitimer);
    olli.addEventListener("click", olliclick, false);
}

function animate_ol(obj, value) {
    if (value > 0) {
        var speed = -20*value;
    }
    if (value < 0) {
        var speed = -20*value;
    }
    var lastleft = obj.offsetLeft;
    obj.timer = setInterval(function () {
        var distance = Math.abs(value * liWidth) - Math.abs(obj.offsetLeft - lastleft);
        if (distance < Math.abs(speed)) {
            clearInterval(obj.timer);
            if (value > 0) {
                clearInterval(obj.timer);
                obj.style.left = obj.offsetLeft - distance + "px";
                flag = true;
            }
            if (value < 0) {
                clearInterval(obj.timer);
                obj.style.left = obj.offsetLeft + distance + "px";
                flag = true;
            }
        }
        else {
            obj.style.left = obj.offsetLeft + speed + "px";
        }
    }, 1);
    index = index + value;
    btnShow(index);
}
Copy after login

Related recommendations:

Native js implementation of carousel chart

Native javascript implements image carousel effect code

The above is the detailed content of How to implement a carousel using native JavaScript? Detailed code explanation. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template