Nanny-style native Js simple carousel diagram + slow animation packaging tutorial

The principle of the carousel:
a series of pictures of equal size are tiled, and only one picture is displayed using CSS layout, and the rest are hidden. Use the timer to realize automatic playback by calculating the offset, or switch the picture by manually clicking the event.
Insert picture description here
HTML layout The
parent container box stores all the content, the child container screen stores the picture, and current stores the button number. When
left/right is moved, an arrow appears, click left and right to slide the picture effect

<div class="all" id='box'>        
  <div class="screen">            
    <ul>                
      <li><img src="image/timg.jpg" width="500" height="200" /></li>                
      <li><img src="image/11.jpg" width="500" height="200" /></li>                
      <li><img src="image/timg2.jpg" width="500" height="200" /></li>                
      <li><img src="image/timg3.jpg" width="500" height="200" /></li>                
      <li><img src="image/timg4.jpg" width="500" height="200" /></li>            
    </ul>            
    <ol>                
      <li class="current">1</li>                
      <li>2</li>                
      <li>3</li>                
      <li>4</li>               
      <li>5</li>            
    </ol>
  </div>        
        <div id="arr"><span id="left">&lt;</span><span id="right">&gt;</span></div>    
  </div>


Set overflow: hidden in the CSS layout screen; you can only display the viewport size picture, and the rest is hidden.
The comment here is to facilitate the observation of the effect.

 <style type="text/css">        
 * {
    
                
    padding: 0;            
    margin: 0;            
    list-style: none;            
    border: 0;        
}
        
 .all {
    
               
     width: 500px;            
     height: 200px;           
     padding: 7px;            
     border: 1px solid #ccc;            
     margin: 100px auto;            
     position: relative;        
}
.screen {
    
                
      width: 500px;            
      height: 200px;            
      /* overflow: hidden; */            
      position: relative;        
}
.screen li {
    
                
          width: 500px;            
          height: 200px;           
          overflow: hidden;            
          float: left;        
}
 .screen ul {
    
                
       position: absolute;            
       left: 0;            
       top: 0px;           
       width: 3500px;//五张图片加两张复制的宽度        
 }
       
.all ol {
    
                
        position: absolute;            
        right: 10px;            
        bottom: 10px;            
        line-height: 20px;            
        text-align: center;        
 }
.all ol li {
    
                
       float: left;            
       width: 20px;            
       height: 20px;            
       background: #fff;            
       border: 1px solid #ccc;            
       margin-left: 10px;            
       cursor: pointer;        
}
.all ol li.current {
    
                
         background: yellow;        
}
#arr {
    
                
   display: none;        
   }
#arr span {
    
                
   width: 40px;            
   height: 40px;            
   position: absolute;            
   left: 5px;            
   top: 50%;            
   margin-top: -20px;            
   background: #000;            
   cursor: pointer;            
   line-height: 40px;            
   text-align: center;            
   font-weight: bold;            
   font-family: '黑体';            
   font-size: 30px;           
   color: #fff;            
   opacity: 0.3;           
   border: 1px solid #fff;        
}
 #arr #right {
    
                
    right: 5px;            
    left: auto;        
}   
 </style>

js part
1: When the mouse enters, the left and right arrows are displayed, the mouse is moved out, and the arrows are hidden

Get relevant data to be operated on

let box = document.getElementById('box');
let arr = document.getElementById('arr');
let left = document.getElementById('left');
let right = document.getElementById('right');
let screen = box.querySelector('.screen');
let ul = screen.querySelector('ul');
let ol = screen.querySelector('ol');
let uLis = ul.children;
let oLis = querySelectorAll('li');

Move in event: box event onmouseover: show div#arr
move out event: box event onmouseout: hide div#arr

box.onmouseover = function () {
    
    
    arr.style.display = 'block';
};
box.onmouseout = function () {
    
    
    arr.style.display = '';
};

2: Click the arrows on the left and right, to the left, to see the previous picture; to the right, to see the next picture

Optimization, seamless scrolling.
When switching from the last picture back to the first picture, there will be a big gap transition, use two auxiliary pictures to fill this gap.
Here is a supplement to seamless scrolling, look directly at the code, copy the last picture and place it before the first picture, and copy the first picture and place it behind the last picture.

//拿到图片:第一个li和最后一个li(深克隆)
let first = uLis[0].cloneNode(true);
let last = uLis[uLis.length - 1].cloneNode(true);
//将第一张放到最后,最后一张放到最前
ul.insertBefore(last, uLis[0]);
ul.appendChild(first);

What the user should see is the first picture: move the entire ul 500 to the left: screen.offsetWidth == 500

 box.style.left = -screen.offsetWidth + 'px';

Insert picture description here
3. Define a variable (global): used to record the position of the current picture:

let index = 1;//1 此时代表是真正的第1张(也就是现在的第2张)

Insert picture description here

Encapsulate a slow animation as an effect, which can be called at any time in the future.
Create a document with a suffix of .js.

/** 
 * 缓速动画(向右移动)
 * @param {element} ele ,要移动的元素
 * @param {number} target,要移动的目标位置
*/
function animateSlow(ele, target) {
    
    
// 清理定时器:元素自己的定时器,自己保存
// ele.timeId 访问ele对象的timeId属性:没有得到的结果undefined
   clearInterval(ele.timeId);      // 有就清除,没有就什么都没做
// ele的移动:将当前元素自己的定时器存到自己的对象属性中
   ele.timeId = setInterval(function () {
    
    
  // 拿到ele的边距
     let left = ele.offsetLeft;
  // 计算步长
 // 如果是向右移动:最终是1px移动:Math.ceil(小数) 得到1
 // 如果是向左移动:最终是-1px移动:Math.ceil(-小数) 得到0
 // let step = Math.ceil((target - left) * 0.1);

// 让step根据目标结果(可正可负)
   let step = (target - left) * 0.1;
// 根据step的正负关系:求最小的1px
// step > 0 :target(目标)比left(当前位置)大,向右移动:+1
// step < 0 :target(目标)比left(当前位置)小,向左移动:-1
   step = step > 0 ? Math.ceil(step) : Math.floor(step);
// 计算下一个位置
   let next = left + step;
// console.log(left, step);
// 判定位置
   if (next == target) {
    
    
    // 下一步要到target:直接设定target
       ele.style.left = target + 'px';
    // 终止定时器:定时器存储在自己ele的属性中
       clearInterval(ele.timeId);
    // 结束当前函数
      return;
}
// 正常移动
   ele.style.left = next + 'px';
    }, 20);
};

Introduce animation js document
4. Click the left button event operation: move ul, move is the width corresponding to the screen (li)

// left.onclick = funciton(){};    // 匿名回调
left.onclick = leftClick;
function leftClick() {
    
    
 // 看前一张:下标-1即可
 index--;
 //  做动画:index变成了0,让ul移动:移动 -index * screen.offsetWidth
animateSlow(ul, -index * screen.offsetWidth);
}

After you keep clicking to run, you will find that there is a blank, and you can only go back by right-clickingInsert picture description here

function leftClick() {
    
    
if (index == 0) {
    
    
    //index--就表示前面一张图片,如果index已经等于0:说明当前的图片本质是看的最后一张(效果是第一张):为了保证动画效果
    // 让index瞬间变成倒数第二张:最后加了个第一张
    index = uLis.length - 2;
    // 让ul瞬间移动到倒数第二张
    ul.style.left = -index * screen.offsetWidth + 'px';
}
 // 看前一张:下标-1即可
 index--;
 //  做动画:index变成了0,让ul移动:移动 -index * screen.offsetWidth
animateSlow(ul, -index * screen.offsetWidth);
}

Insert picture description here
Same for the right, let ul move to the left

right.onclick = rightClick;
function rightClick() {
    
    
    // 如果index已经是最后一张:本质代表的是有效第一张:瞬移到一张:index应该重置为1
    if (index == uLis.length - 1) {
    
    
        index = 1; // 回到第一张(此时看的是最后一张)
        // 瞬移到第一张
        ul.style.left = -screen.offsetWidth + 'px';
    }
    index++;
    // 3. 动画效果
    animateSlow(ul, -index * screen.offsetWidth);

Insert picture description here
Unpack the hidden comments in the css style, and the general look is made. You can click left and right to try the effect.
Next, click the left and right buttons to convert the number according to the picture.

function leftClick() {
    
    
if (index == 0) {
    
    
// 要考虑index = 0,本身当前看到的是第5张,下一次要看第4张
oLis[index == 0 ? oLis.length - 1 : index - 1].classList.remove('current');//去除赋值给li下标的类名
       index = uLis.length - 2;
    ul.style.left = -index * screen.offsetWidth + 'px';
}
 index--;
animateSlow(ul, -index * screen.offsetWidth);
oLis[index == 0 ? oLis.length - 1 : index - 1].classList.add('current');//赋值给已经自减li下标的类名
}

right

right.onclick = rightClick;
function rightClick() {
    
    
    oLis[index == uLis.length - 1 ? 0 : index - 1].classList.remove('current');
// 如果index已经是最后一张:本质代表的是有效第一张:瞬移到一张:index应该重置为1
    if (index == uLis.length - 1) {
    
    
        index = 1;
        ul.style.left = -screen.offsetWidth + 'px';
    }
    index++;
 
    animateSlow(ul, -index * screen.offsetWidth);
    oLis[index == uLis.length - 1 ? 0 : index - 1].classList.add('current');

Click on the page number to jump directly to the corresponding picture

// 1. oLis里面的li的下标与 index之间的关系: oLis的下标 + 1 = index
oLis.forEach(function (item, key) {
    
    
//item代表元素,key代表下标
    item.onclick = function () {
    
    
        let oldOlisKey = index - 1;
        if (index == 0) oldOlisKey = oLis.length - 1;
        if (index == 6) oldOlisKey = 0;
        //求出原来的页面的下标: 去除原来页码的样式
        oLis[oldOlisKey].classList.remove('current');
        //计算index当前的值: index = 当前页码下标 + 1
        index = key + 1;
        console.log(index)
        //利用index动画效果实现
        animateSlow(ul, -index * screen.offsetWidth);
        //将当前页面对应的样式: 高亮显示        
        item.classList.animateSlow('current');

The carousel picture will move by itself, and timers are indispensable. Timers have two types: setTimeout (callback function, time interval) and setInterval (callback function, time interval). The former is executed once and the latter is infinite.
Finally, the timer triggers automatic direction Right carousel: let variable = setInterval (callback function, milliseconds);
write it at the beginning of the page to get the element and add it.

let timeId = setInterval(rightClick, 3000);

Enhanced version: When the mouse moves into the box: clear the automatic carousel timer.
Added to the beginning of the page box move into function

 clearInterval(timeId);

When the mouse moves out of the box: continue the carousel and
add it to the box removal function at the beginning of the page

timeId = setInterval(rightClick, 3000);

Summary: To clearly understand the subscript/picture playback mode, the amount of code is not too much, just copy and paste on the left and right to modify it.
Incidentally, an animation is also encapsulated, which accounts for the code, and you can modify it according to your own needs. You can leave a message if you don't understand or suggest.

Guess you like

Origin blog.csdn.net/weixin_47886687/article/details/108222628