Case: Web carousel map

Keywords: Javascript Front-end

z case: Web carousel map
Also known as focus map

Functional requirements:
When the mouse passes through the rotation chart module, the left and right buttons are displayed and the left and right buttons are hidden
Click the button on the right once, and the picture will be played to the left once, and so on. The same is true for the left button
While the picture is playing, the following small circle module changes with it
Click the small circle to play the corresponding picture
If the mouse does not pass through the rotation map, the rotation map will be played automatically
When the mouse passes through the rotation diagram module, the automatic playback stops
Module:
Dynamically generate small circles:
Core idea: the number of small circles should be consistent with the number of pictures
First, get the number of pictures in ul (pictures are placed in li, so it is the number of li)
Use the loop to dynamically generate a small circle (this small circle should be put into ol)
Create node createElement ('li ')
Insert node ol.appendchild (LI)
Add the class name li.children[0].className = "current" to the first small circle;
Click the small circle to play the corresponding picture
Exclusive thought: click the current small circle to add the current class, and the rest will remove this class

Click the small circle to scroll the picture
At this time, the animate function is used to import the JS file. Because index.js depends on animate.js, animate.js must be written to index.js
The element must have positioning before using animation functions
It's ul mobile, not li
Core algorithm for scrolling pictures: click a small circle, and the index number of the small circle will be multiplied by the width of the picture (negative value) as the moving distance of ul
At this time, we need to know the index number of the small circle. We can set a user-defined attribute for the small circle when it is generated, and click to obtain the user-defined attribute
Click the button on the right once, and the picture will be played to the left once
Declare a variable num, click once and increase by one. Multiply this variable by the picture width, which is the scroll distance of ul
Seamless picture scrolling is used when the picture scrolls to the last one
Seamless picture scrolling principle: copy the first li of ul and put it at the back of ul
When the picture scrolls to the last one, let ul quickly jump to the far left without Animation: left is 0
At the same time, assign num to 0 and start scrolling again
Clone the first picture
Clone ul the first li cloneNode() plus true deep clone copy the child node inside false shallow clone
Add to ul rearmost appendChild
-While the picture is playing, the following small circle module changes with it

The simplest way is to declare another variable circle. Each time you click it, add one. Note: the button on the left also needs this variable, so declare the global variable
Because the first picture was cloned, the small circle is one less than the picture, and a judgment condition should be added: if circle = number of pictures - 1 indicates that the cloned picture has arrived. At this time, let circle = 0 recover
Auto play
Add a timer
Automatically play the rotation chart, which is actually similar to clicking the right button
At this point, we use the button on the right to manually call and click the event arrow_r.click()
When the mouse passes focus, the timer stops
throttle valve
It is used to prevent the rotation chart from playing too fast due to continuous clicking

Throttle valve purpose: when the last function animation is completed, execute the next function animation, so that events cannot be triggered continuously

Core idea: use callback function to add a variable to control, lock function and unlock function

Start setting a variable var flag = true;
If (flag) {flag = flag; do something;} turn off the faucet
Using the callback function, after the animation is executed, flag = true, turn on the faucet
(os: but I don't know why the following code can't realize the throttle function, so I didn't add it. If a big man sees it and knows how to change it, please give me some advice.)
If a throttle valve is added, the layout should be the following style:
 

 var flag = true; //throttle valve
  arrow_r.addEventListener("click", function () {
    if (flag) {
      flag = false;
      //If you get to the last copy ul, quickly restore the left to 0
     .........
      animate(ul, -num * focusWidth, function () {
        flag = true; //Open the throttle valve
      });
    .........
    }
  });
 arrow_l.addEventListener("click", function () {
    if (flag) {
      flag = false;
      //If you get to the last copy ul, quickly restore the left to 0
     ...........
      animate(ul, -(num * focusWidth), function () {
        flag = true;
      });
    ...........
    }
  });

code:
HTML code:

   <!-- Introduction of home page css file -->
   <link rel="stylesheet" href="css/index.css" />
   <!-- introduce JS file -->
   <script src="js/animate.js"></script>
   <!--this JS File must be written to index.js above-->
   <script src="js/index.js"></script>
  </head>

  <body>
     <div class="focus fl">
          <!-- Left button -->
          <a href="javascript:;" class="arrow_l"> &lt; </a>
          <!-- Right button -->
          <a href="javascript:;" class="arrow_r"> &gt; </a>
          <!-- Must use ul Layout the scrolling area of the effect core of the carousel -->
          <!-- There are several li There are several pictures in the rotation picture -->
          <ul>
            <li>
              <a href="#"><img src="upload/focus1.jpg" /></a>
            </li>
            <li>
              <a href="#"><img src="upload/focus2.jpg" /></a>
            </li>
            <li>
              <a href="#"><img src="upload/focus3.jpg" /></a>
            </li>
            <li>
              <a href="#"><img src="upload/focus4.jpg" /></a>
            </li>
          </ul>
          <!-- Small circle -->
          <ol class="circle"></ol>
   </div> 

CSS code:

.fl {
    float: left;
} 
.focus {
  position: relative;
  height: 440px;
  width: 721px;
  background-color: purple;
  overflow: hidden;
}
.focus ul {
  position: absolute; /*Animation can only be used with positioning*/
  top: 0;
  left: 0;
  width: 600%; /*Set it to 600% of the width of the parent box to ensure that the four pictures of the rotation map are wide enough to float*/
}
.focus ul img {
  width: 720px;
  height: 440px;
  float: left;
}
.arrow_l,
.arrow_r {
  display: none; /*Hide the button first for the effect of the rotation picture*/
  position: absolute;
  top: 50%; /* Walk half the height of your father */
  transform: translateY(-50%); /* Walk half your height */
  width: 24px;
  height: 40px;
  background: rgba(0, 0, 0, 0.3);
  font-family: "icomoon";
  font-size: 18px;
  text-align: center;
  line-height: 40px;
  color: #fff;
  z-index: 2; /*Add a hierarchy to display it in ul*/
}
.arrow_r {
  right: 0;
}
.circle {
  position: absolute;
  bottom: 10px;
  left: 50px;
}
.circle li {
  float: left;
  width: 8px;
  height: 8px;
  /* background-color: #fff; */
  border: 2px solid rgba(255, 255, 255, 0.5);
  margin: 0 3px;
  border-radius: 50%;
  /* Mouse over display small hand */
  cursor: pointer;
}
.current {
  background-color: #fff;
}

JS code:

window.addEventListener("load", function () {
  //Preload
  //1. Get element
  var arrow_l = document.querySelector(".arrow_l");
  var arrow_r = document.querySelector(".arrow_r");
  var focus = document.querySelector(".focus");
  var focusWidth = focus.offsetWidth; //Get picture width

  //2. The mouse passes through the rotation map area and the left and right buttons are displayed
  focus.addEventListener("mouseenter", function () {
    arrow_l.style.display = "block";
    arrow_r.style.display = "block";
    //Stop timer, stop auto play
    clearInterval(timer);
    timer = null; //Clear timer variable
  });

  //When the mouse leaves the rotation chart area, the left and right buttons are hidden
  focus.addEventListener("mouseleave", function () {
    arrow_l.style.display = "none";
    arrow_r.style.display = "none";
    //Turn on the timer and auto play starts
    timer = setInterval(function () {
      //Manually call click event
      arrow_r.click();
    }, 2000);
  });

  //3. Dynamically generate a small circle. If there are several pictures in it, create several small dots
  var ul = focus.querySelector("ul");
  var ol = focus.querySelector(".circle");
  for (var i = 0; i < ul.children.length; i++) {
    //Create a li
    var li = document.createElement("li");
    //The index number of the current small circle is recorded through the user-defined attribute
    li.setAttribute("index", i);
    //Insert li into ol
    ol.appendChild(li);

    //4. Exclusive events of small circles can be directly bound to events while generating small circles
    // Click the current small circle to add the current class, and the rest will remove this class
    li.addEventListener("click", function () {
      //(1) Kill everyone and clear the current class name
      for (var i = 0; i < ol.children.length; i++) {
        ol.children[i].className = "";
      }
      //(2) Leave the current class name and add it yourself
      this.className = "current";

      //5. Click the small circle to move the picture, and the moving is ul
      //ul moving distance: the index number of the small circle multiplied by the width of the picture (negative value)
      //Click the small circle to get the index number of the current li
      var index = this.getAttribute("index");
      //When a li is clicked, the index number of the li is given to num
      num = index;
      //When a li is clicked, the index number of the li is given to the circle
      circle = index;
      animate(ul, -(index * focusWidth));
    });
  }

  //Add the class name current to the first ol small circle
  ol.children[0].className = "current";
  //6. Clone the first picture and put it at the back
  var first = ul.children[0].cloneNode(true);
  ul.appendChild(first);

  //7. Click the button on the right to scroll one picture
  var num = 0;
  var circle = 0; //Controls the playback of small circles
  //var flag = true; // throttle valve
  arrow_r.addEventListener("click", function () {
    //If you get to the last copy ul, quickly restore the left to 0
    if (num == ul.children.length - 1) {
      ul.style.left = 0;
      num = 0;
    }
    num++;
    animate(ul, -num * focusWidth);
    //8. Click the button on the right, and the small circle will change together. You can declare another variable to control the playback of the small circle
    //If circle = 4, it's the end, and restore
    circle++;
    if (circle == ol.children.length) {
      circle = 0;
    }
    circleChange(); //Call function
  });

  //9. Click the button on the left to scroll one picture
  arrow_l.addEventListener("click", function () {
    //If you get to the last copy ul, quickly restore the left to 0
    if (num == 0) {
      num = ul.children.length - 1;
      ul.style.left = -num * focusWidth + "px";
    }
    num--;
    animate(ul, -(num * focusWidth));
    //Click the button on the left, and the small circle will change together. You can declare another variable to control the playback of the small circle
    circle--;
    //If circle < 0, it means the first picture. At this time, the small circle should be changed to the fourth small circle (3)
    if (circle < 0) {
      circle = ol.children.length - 1;
    }
    circleChange(); //Call function
  });

  function circleChange() {
    //Clear the remaining small circle class names first
    for (var i = 0; i < ol.children.length; i++) {
      ol.children[i].className = "";
    }
    //Leave the current class name of the current small circle
    ol.children[circle].className = "current";
  }

  //10. Auto play function
  var timer = setInterval(function () {
    //Manually call click event
    arrow_r.click();
  }, 2000);
});

Posted by Yeti on Sat, 04 Dec 2021 21:31:17 -0800