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"> < </span> <span id="right"> > </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"> < </span> <span id="right"> > </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>