Native Js to realize automatic and seamless carousel graph

Posted by chet23 on Tue, 16 Jun 2020 10:21:07 +0200

javascript implementation of automatic seamless rotation chart

1. Implementation principle

The principle of the implementation of the rotation chart is to use a large box group container, which contains a small box for moving. The small box contains pictures to be rotated. The pictures are horizontally arranged. When the small box moves, the pictures are moved together. To achieve seamless rotation, a picture similar to the first one is placed at the end. When the pictures are rolled to the last one, use the The user will feel that this is the first picture, and then jump to the first picture, so that the user will not feel that the picture is jumping in the past, and realize seamless rotation

2. Achieving results


(there are size restrictions on image upload, here is a part of...)

3. Code display

3.1 page structure layout (html code)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="css/case.css">
</head>
<body>
    <div id="view">
        <div id="banner">
            <ul id="ul">
                <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>
            <!-- Small dots are used to display the number of pictures -->
            <ol id="bar"> 
			<!-- Because we need to dynamically obtain the number of pictures for display, we can't write it dead here -->
            </ol>
            <!-- Left and right focus -->
            <div id="fouse" style="display: none;">
                <span id="left">
                    &lt;
                </span>
                <span id="right">
                    &gt;
                </span>
            </div>
        </div>
    </div>

3.2 style (css code)

* {
    margin: 0;
    padding: 0;
}
#view {
    width: 400px;
    height: 600px;
    margin: 100px auto;
    border: 1px solid #000
}
#banner {
    width: 400px;
    height: 600px;
    position: relative;
    overflow: hidden;
}
#banner img {
    width: 400px;
    height: 600px;
    vertical-align: top;
}
#ul {
    width: 1000%;
    position: absolute;
    left: 0;
    top: 0;
    list-style: none;
}
#banner li {
    float: left;
}
#fouse {
    width: 100%;
    height: 50px;
    position: absolute;
    left: 0;
    top: 50%;

}
#fouse span {
    width: 50px;
    height: 50px;
    text-align: center;
    font-size: 50px;
    line-height: 50px;
    color: #fff;
    cursor: pointer;
    font-weight: bold;
    opacity: 0.5;
    
}
#fouse #left {
    float: left;
}
#fouse #right {
    float: right;
}
ol {
    position: absolute;
    height: 20px;
    right: 20px;
    bottom: 20px;
    text-align: center;
    padding: 5px;
}
ol li {
    display: inline-block;
    width: 20px;
    height: 20px;
    line-height: 20px;
    background: #fff;
    margin: 5px;
    cursor: pointer;
}
ol .current {
    background-color: pink;
}

3.3 core JS code

Get the element first, and then operate

var view = document.getElementById("view");
        var banner = document.getElementById("banner");
        var fouse = document.getElementById("fouse");
        var ulObj = banner.children[0];
        var list = ulObj.children;
        var olObj = banner.children[1];
        var imgWidth = banner.offsetWidth;
        var pic = 0;
        var left = document.getElementById("left");
        var right = document.getElementById("right");

Because of the dynamic creation of small dots, we use for loop to traverse the list of pictures and create small dots

for(var i = 0; i < list.length; i++) {
            var liObj = document.createElement("li");
            olObj.appendChild(liObj);
            liObj.innerText = (i + 1);
            //Dynamically add an index attribute to a small circle
            liObj.setAttribute("index", i)
}

Move the mouse over a small dot to jump to the specified picture, so register an onmouseover event for the small dot button

liObj.onmouseover = function() {
                //Clear all styles
                for(var j = 0; j < olObj.children.length; j++) {
                    olObj.children[j].removeAttribute("class");
                }
                this.className = "current";
                pic = this.getAttribute("index");
    			//animate is a self encapsulating method for moving pictures
                animate(ulObj,-pic*imgWidth);
            }
        }

Add style to the first button by default

olObj.children[0].className = "current";

To achieve seamless rotation, clone the first picture

ulObj.appendChild(ulObj.children[0].cloneNode(true))

Turn on timer

var timeId = setInterval(onMouseClickHandle,1000)
function onMouseClickHandle () {
            //If the pic value is 5, the sixth picture (the content is the first picture) will be displayed. The user will think that the first picture is the first picture, so when the user clicks the next picture, the second picture should be displayed
            if(pic == list.length - 1) {
                //How to change from the sixth to the first
                pic = 0;
                ulObj.style.left = 0 + 'px'//Let ul's go back to the default position
            }
            pic++//Pic + + now pic=1
            animate(ulObj, -pic * imgWidth)
            
            if(pic == list.length - 1) {
                //Clear the style of all small circle points, and set the first small circle point to be highlighted
                olObj.children[olObj.children.length - 1].className = '';
                olObj.children[0].className = "current"
            }
            else {
                for(var i = 0; i < olObj.children.length; i++) {
                    olObj.children[i].removeAttribute("class");
                }
                olObj.children[pic].className = "current"
            }
        }

Encapsulates the function used to move any element to a specified location

 function animate(elem, target) {
            clearInterval(elem.timeId);
            elem.timeId  = setInterval(function() {
                //Gets the current element location, which is a numeric type
                var current = elem.offsetLeft;
                //Set the distance to move once
                var step = 10;
                //When the inequality holds, the result is the value before the colon, otherwise it is the value after the colon
                step = current < target ? step : -step;
                current += step;
                if(Math.abs(current - target) > Math.abs(step)) {
                    elem.style.left = current + "px"
                }else {
                    //Clear timer
                    clearInterval(elem.timeId);
                    //Arrive at the designated location
                    elem.style.left = target + "px"
                }
            },10)
        }

Set interaction events for users

view.onmouseover = function() {
            //Mouse over, display toggle button and clear timer
            fouse.style.display = "block"
            clearInterval(timeId)
        } 
        view.onmouseout = function() {
            //Move the mouse away, hide the toggle button and turn on the timer
            timeId = setInterval(onMouseClickHandle,1000)
            fouse.style.display = "none"
        }

        //Click to switch to the next one
        right.onclick = onMouseClickHandle;
        //Click to switch to the previous one
        left.onclick = function() {
            //If this is the first picture
            if(pic == 0) {
                pic = list.length - 1;
                ulObj.style.left = -pic * imgWidth + "px";
                
            }
            pic --;
            animate(ulObj, - pic * imgWidth);
            for(var i = 0;i < olObj.children.length; i++) {
                olObj.children[i].removeAttribute("class");
            }
            olObj.children[pic].className = "current"
        }

3.4 complete code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        #view {
            width: 400px;
            height: 600px;
            margin: 100px auto;
            border: 1px solid #000
        }
        #banner {
            width: 400px;
            height: 600px;
            position: relative;
            overflow: hidden;
        }
        #banner img {
            width: 400px;
            height: 600px;
            vertical-align: top;
        }
        #ul {
            width: 1000%;
            position: absolute;
            left: 0;
            top: 0;
            list-style: none;
        }
        #banner li {
            float: left;
        }
        #fouse {
            width: 100%;
            height: 50px;
            position: absolute;
            left: 0;
            top: 50%;

        }
        #fouse span {
            width: 50px;
            height: 50px;
            text-align: center;
            font-size: 50px;
            line-height: 50px;
            color: #fff;
            cursor: pointer;
            font-weight: bold;
            opacity: 0.5;
            
        }
        #fouse #left {
            float: left;
        }
        #fouse #right {
            float: right;
        }
        ol {
            position: absolute;
            height: 20px;
            right: 20px;
            bottom: 20px;
            text-align: center;
            padding: 5px;
        }
        ol li {
            display: inline-block;
            width: 20px;
            height: 20px;
            line-height: 20px;
            background: #fff;
            margin: 5px;
            cursor: pointer;
        }
        ol .current {
            background-color: pink;
        }
    </style>
</head>
<body>
    <div id="view">
        <div id="banner">
            <ul id="ul">
                <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>
            <!-- DoT -->
            <ol id="bar"> 

            </ol>
            <!-- Left and right focus -->
            <div id="fouse" style="display: none;">
                <span id="left">
                    &lt;
                </span>
                <span id="right">
                    &gt;
                </span>
            </div>
        </div>
    </div>

    <script>
        //Get elements for later operation
        var view = document.getElementById("view");
        var banner = document.getElementById("banner");
        var fouse = document.getElementById("fouse");
        var ulObj = banner.children[0];
        var list = ulObj.children;
        var olObj = banner.children[1];
        var imgWidth = banner.offsetWidth;
        var pic = 0;
        var left = document.getElementById("left");
        var right = document.getElementById("right");

        //Because it is a dynamic creation of small dots, it cannot be written to death. Use for loop to traverse ul, get the number of pictures, and then create small dots
        for(var i = 0; i < list.length; i++) {
            var liObj = document.createElement("li");
            olObj.appendChild(liObj);
            liObj.innerText = (i + 1);
            //Dynamically add an index attribute to a small circle
            liObj.setAttribute("index", i)

            //Register onmouseover event for small dot button
            liObj.onmouseover = function() {
                //Clear all styles
                for(var j = 0; j < olObj.children.length; j++) {
                    olObj.children[j].removeAttribute("class");
                }
                this.className = "current";
                pic = this.getAttribute("index");
                animate(ulObj,-pic*imgWidth);
            }
        }


        olObj.children[0].className = "current";
        //To achieve seamless rotation, the first image should be cloned at the end of the picture list by using the visual difference
        ulObj.appendChild(ulObj.children[0].cloneNode(true))
        var timeId = setInterval(onMouseClickHandle,1000)
        view.onmouseover = function() {
            //Mouse over, display toggle button and clear timer
            fouse.style.display = "block"
            clearInterval(timeId)
        } 
        view.onmouseout = function() {
            //Move the mouse away, hide the toggle button and turn on the timer
            timeId = setInterval(onMouseClickHandle,1000)
            fouse.style.display = "none"
        }

        //Click to switch to the next one
        right.onclick = onMouseClickHandle;
        //Click to switch to the previous one
        left.onclick = function() {
            //If this is the first picture
            if(pic == 0) {
                pic = list.length - 1;
                ulObj.style.left = -pic * imgWidth + "px";
                
            }
            pic --;
            animate(ulObj, - pic * imgWidth);
            for(var i = 0;i < olObj.children.length; i++) {
                olObj.children[i].removeAttribute("class");
            }
            olObj.children[pic].className = "current"
        }
        
        function onMouseClickHandle () {
            //If the pic value is 5, the sixth picture (the content is the first picture) will be displayed. The user will think that the first picture is the first picture, so when the user clicks the next picture, the second picture should be displayed
            if(pic == list.length - 1) {
                //How to change from the sixth to the first
                pic = 0;
                ulObj.style.left = 0 + 'px'//Let ul's go back to the default position
            }
            pic++//Pic + + now pic=1
            animate(ulObj, -pic * imgWidth)
            
            if(pic == list.length - 1) {
                //Clear the style of all small circle points, and set the first small circle point to be highlighted
                olObj.children[olObj.children.length - 1].className = '';
                olObj.children[0].className = "current"
            }
            else {
                for(var i = 0; i < olObj.children.length; i++) {
                    olObj.children[i].removeAttribute("class");
                }
                olObj.children[pic].className = "current"
            }
        }

        //Encapsulates functions that move any element to a specified location
        function animate(elem, target) {
            clearInterval(elem.timeId);
            elem.timeId  = setInterval(function() {
                //Gets the current element location, which is a numeric type
                var current = elem.offsetLeft;
                //Set the distance to move once
                var step = 10;
                //When the inequality holds, the result is the value before the colon, otherwise it is the value after the colon
                step = current < target ? step : -step;
                current += step;
                if(Math.abs(current - target) > Math.abs(step)) {
                    elem.style.left = current + "px"
                }else {
                    //Clear timer
                    clearInterval(elem.timeId);
                    //Arrive at the designated location
                    elem.style.left = target + "px"
                }
            },10)
        }

        
    </script>
</body>
</html>





Topics: Attribute Javascript