Effect: Rock Slider

structure

In the above picture, the whole rotation chart is placed in a div with a class of slider. It can be seen that the whole rotation is composed of three parts:

  • Picture part
  • Forward and back buttons
  • dots

Img tags can be used for several images, a tag can be used for the forward and back buttons, note that the default event is removed, small dots can be an unordered list, based on the above idea, you can write the following HTML code

<div class="slider">
      <img class="fade" src="./img/1.jpg" alt="" />
      <img class="fade" src="./img/2.jpg" alt="" />
      <img class="fade" src="./img/3.jpg" alt="" />
      <img class="fade" src="./img/4.jpg" alt="" />

      <a class="prev" onclick="prev()">&lt;</a>
      <a class="next" onclick="next()">&gt;</a>

      <ul class="nav">
        <li class="dot selected" onclick="turnToSlide(0)"></li>
        <li class="dot" onclick="turnToSlide(1)"></li>
        <li class="dot" onclick="turnToSlide(2)"></li>
        <li class="dot" onclick="turnToSlide(3)"></li>
      </ul>
</div>
Copy the code

To explain the class names, img’s fade is used to write transitions, prev, next is used to write forward and backward styles, nav is used to control the unordered list arrangement, dot is the unselected style for each dot, and Selected is the selected style.

layout

I feel that the logic of the round broadcast map is not very difficult, difficult in the layout

We need to use an idea called “Zi jiu fu xiang”, which means that the position attribute of the father is relative and the position of the son is absolute. It is convenient to adjust the position of the son. Therefore, we set the position of slider to relative. The position of its immediate descendant element is set to absolute.

It’s easy to see that the forward and back buttons are centered vertically by the edge, so set left/right to 0, and then center vertically, giving the top attribute 50%, but the top distance is based on the upper left corner of the element, so to really center we have to shift the element up 50% of its height, You can use transform: translateY(-50%); I won’t bore you with the style details, the code is easy to read.

The navigation dot is vertically centered at the bottom, so we set bottom to a smaller value, leaving the point distance, and then left:50; ,transform: translateX(-50%); , the specific style can be adjusted according to their preferences.

The code is as follows:

    .slider {
        top: 50%;
        left: 50%;
        transform: translate(-50%);
        width: 60vw;
        position: relative;
      }

      @media screen and (max-width: 900px) {
        .slider {
          width: 100vw; }}.slider img {
        display: none;
        width: 100%;
        border-radius: 4px;
      }
      .prev..next {
        position: absolute;
        top: 50%;
        width: 20px;
        height: 30px;
        transform: translateY(-50%);
        color: white;
        font-size: 24px;
        font-weight: bold;
        cursor: pointer;
        padding: 10px;
        user-select: none;
        transition: 0.6 s ease;
      }
      .prev {
        border-radius: 0 3px 3px 0;
        left: 0;
      }
      .next {
        right: 0;
        border-radius: 3px 0 0 3px;
      }

      .prev:hover..next:hover {
        background-color: rgba(0.0.0.0.8);
      }

      .nav {
        position: absolute;
        width: 12vmax;
        left: 50%;
        transform: translateX(-50%);
        display: flex;
        justify-content: space-evenly;
        bottom: 1vmin;
      }
      .dot {
        list-style-type: none;
        cursor: pointer;
        background-color: #fff;
        width: 1.5 vmax;
        height: 1.5 vmax;
        border-radius: 50%;
        transition: background-color 0.6 s ease;
      }
      .selected {
        background-color: #ff5000;
      }

      .fade {
        animation-name: fade;
        animation-duration: 1.5 s;
        -webkit-animation-name: fade;
        -webkit-animation-duration: 1.5 s;
      }

      @keyframes fade {
        from {
          opacity: 0.4;
        }
        to {
          opacity: 1; }}@-webkit-keyframes fade {
        from {
          opacity: 0.4;
        }
        to {
          opacity: 1; }}Copy the code

Here it is worth mentioning: for the mobile user experience, do simple mobile adaptation, using media query and responsive units.

As for @keyframes animation, if you don’t understand it, go to MDN and look at the documentation.

action

Finally, look at the logical part.

At initialization, set the display property of each image to None, and then set the display property of each image to block. The first image is played when the page loads.

In order to realize the three functions of forward, backward, and clicking the dot to display the specified picture, we should at least implement the three functions of Next, Prev, and turnToSlide. The logic of these three functions is to play the specified picture after clicking, so we can consider implementing a playback function showSlide, which plays according to the index of the picture. Then because the rotation chart is automatic playback function, we should consider adding a timer in it (use timer to pay attention to empty), to achieve regular playback.

Based on the above design, we write the following code

    function Slider () {
        let slideIndex = 0
        let timer,
          flag = 0

        function deleteTimer () {
          clearTimeout(timer)
          timer = null
        }

        function next () {
          slideIndex++
          showSlide()
        }

        function turnToSlide (index) {
          if (index === slideIndex) return
          slideIndex = index
          showSlide()
        }
        function prev () {
          slideIndex--
          showSlide()
        }

        function showSlide () {
          deleteTimer()
          const slides = document.querySelectorAll('img')
          const dots = document.querySelectorAll('.dot')
          if (slideIndex >= slides.length) {
            slideIndex = 0
          }
          if (slideIndex < 0) {
            slideIndex = slides.length - 1
          }
		  
          slides[flag].style.display = 'none'
          dots[flag].classList.remove('selected')

          slides[slideIndex].style.display = 'block'
          dots[slideIndex].classList.add('selected')

          flag = slideIndex

          timer = setTimeout(next, 5000)}return {
          prev,
          next,
          showSlide,
          turnToSlide
        }
      }
      const slider = Slider()
      slider.showSlide()
Copy the code

To prevent global variable contamination, I placed all the methods and variables associated with the Slider inside a function and exposed only the four methods to be called.

In terms of image switching, the current mainstream writing method is to use a for loop and set the display of all images to None and the display of images to be played to block. It could be done, but it’s not necessary. We can record the index of the last image by using a flag variable, so that when I play the new image, I set the display of the image whose index is flag to None, and the display of the image to be played to block.

7Sings /Slider: A simple Slider writen with HTML, CSS and javascript (github.com)

Afterword.

September 7, 2021: Optimized mobile user experience, hides forward and backward buttons on touch screen devices, enables forward and backward functions by swiping left (next slide) and right (previous slide). Because I am lazy, the code is not updated in the article, the updated code see the above warehouse address.

To be continued...