Native JS changes transparency to achieve carousel effect

  • 2021-08-05 08:48:46
  • OfStack

In my opinion, if you want to realize carousel, you should mainly know the current page and the page to be located. In this case, the transparency of the picture is changed to achieve the effect of carousel.

I divide the knowledge points involved into two aspects, namely HTML + css and JS.

Part 1 (html+css)

The knowledge included is: positon positioning.

The outermost layer is an div, which contains all the elements. There are 3 pictures in this carousel 1, which are contained in an unordered list. The outermost div also has two sub-elements to switch between the top 1 picture and the bottom 1 picture. These two sub-elements are also div. Switch the id attribute of div in the last picture to pre, and switch the id attribute of div in the next picture to next. The position value of the outermost div is relative. The position that contains an unordered list of pictures is relative. The positon attribute value of the li element in the unordered list is absolute, which leaves the li element outside the document stream, so the ul height is zero if the height of the ul is not set. But we can't use css to show the height of setting ul. Because you need to make the height of this carousel equal to the height of the picture, and make sure that the aspect ratio of the picture remains the same on computers with different resolutions. On computers with different resolutions, the height and width of pictures are different. So I set the height of ul through js. Because the attribute value of position of ul is relative, the height of ul will spread the height of outer div. Because this case is to realize carousel by changing the transparency of pictures, Therefore, all pictures are located in the same position. By default, the last picture will be at the top, the first picture will be at the bottom, and the picture displayed in the first carousel should be the first picture, then the second picture, and finally the third picture. Therefore, the z-index attributes should be set for each li to be displayed. And the z-index attribute values decrease in turn. I use js to set the z-index attribute value of every li, but it is not necessary to do so. Just use css attribute directly, just write three selectors.

html is as follows:


<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title> Carousel by changing transparency </title>
 <link rel="stylesheet" type="text/css" href="index.css" rel="external nofollow" >
</head>
<body>
 <div class='warp' id='warp'>
 <ul class='list' id='list'>
  <li><img src='img/4274ad202b27b671e622388989399d54.jpg' style='opacity: 1'></li>
  <li><img src='img/299733ddbe89d6b317cc0e84c43999d4.jpg' style='opacity: 1'></li>
  <li><img src='img/9b7ec36280e638929aa10ce0955df3d3.jpg' style='opacity: 1'></li>
 </ul>
 <div class='pre' id='pre'> " </div>
 <div class='next' id='next'> " </div>
 </div>
 <script type="text/javascript" src='index.js'></script>
</body>
</html>

The css code is as follows


*{
 padding: 0;
 margin: 0;
}
.warp{
 position: relative;
 width: 100%;
}
.list{
 position: relative;
 width: 100%;
}
.list li{
 position: absolute;
 top:0;
 left: 0;
 width: 100%;
 list-style: none;
 opacity: 1;
}
li img{
 width: 100%;
}
.pre,.next{
 position: absolute;
 top: 50%;
 bottom: 0;
 width: 64px;
 height: 64px;
 z-index: 10;
 margin-top: -32px;
 text-align: center;
 line-height: 64px;
 color: #fff;
 font-weight: bold;
 font-size: 30px;
 cursor: pointer;
 background-color: transparent;
}
.pre{
 left: 20px;
 right: auto;
}
.next{
 right:20px;
 left: auto;
}
.pre:hover,.next:hover{
 background-color: rgba(0,0,0,0.7);
}

Part 2 (js) covers events, function throttling, setting timers, clearing timers
Since the event uses native js to implement its functions, browser compatibility needs to be considered.

Event flow

There are two types of time flow, event bubbling flow and event capture flow, which are almost completely opposite concepts of event flow. Event bubbling flow is called event bubbling, which was proposed by IE. Take an click event as an example. In the event bubbling, the event first occurs on the most specific element, that is, the element we click, and then propagates up the dom tree. In the process of propagation, click events will occur on every level 1 node until the propagated document object. The event capture stream is called event capture, which is proposed by Netscape Communicator. Also take an click event as an example. In event capture, the event first occurs on the least specific node (document object first receives the event), then propagates down the dom tree, and the most specific node finally receives the event, that is, the element actually clicked finally receives the click event. "DOM2 Level Events" stipulates that the event flow includes three stages, namely, the event capture stage, the target stage and the event bubbling stage. In mainstream browsers, DOM event stream is supported except DOM event stream is not supported by IE. Therefore, the support event of IE bubbles. However, IE should support DOM event flow in the future. At that time, you don't have to consider browser compatibility when binding events. For maximum compatibility with various browsers, I'm adding event handlers to the bubbling phase of the event flow.

Event handler

"DOM Level 0 Event Handler

DOM0 level binds events by assigning values to the attributes of elements, and only sets the value of the event handler attribute to 1 function. this in the program refers to the current element. To remove an event method that is bound through an DOM level 0 method, set the property of the event handler to null. If an element is bound to an event, it is best to manually unbind the element to the event before removing the element from the document. This prevents the element from being removed but the reference to its event handler remains in memory. All modern browsers support DOM 0-level event handlers. However, when binding events with DOM0 level, only one event handler can be added to each element with one event.

"DOM2 Level Event Handler

The method of specifying an event handler in "DOM Level 2 Events" is: addEventListener (), the first argument is an event name, the second argument is an event handler (that is, a function, which can be anonymous), and the third argument is a Boolean value. This Boolean value indicates at which stage the event is processed, when false, in the bubbling stage, and when true, in the capture stage. I set this value to false for compatibility. Unbinding time handlers with "DOM Level 2 Events" requires the use of removeEventListener (), and anonymous event handlers cannot be undone. When you bind events using "DOM Level 2 Events", you can add more than one event handler for each element with one event. Event handler for kidnapping with "DOM Level 2 Event", where this refers to the current element.

"IE Event Handler

The way to specify an event handler in IE is attachEvent (), with the first argument being the event handler name (that is, "on" + event name) and the second argument being the time handler (1 function, which can be anonymous). Because IE only supports event bubbling, events are processed in the bubbling stage. Use detachEvent () to remove the time handler added with attachEvent (), but anonymous functions cannot be removed. Use attachEvent () to bind the event this to refer to window. . When you bind events using attachEvent, you can add more than one event handler for each element with one event.

Note: The anonymous function cannot be removed because in js the function is an object that is stored in the heap and the function name is a pointer to an object in the heap. For an anonymous function, there is no pointer to it, so it cannot be accessed.

Event object

In DOM-compliant browsers, the event object is passed to the event handler as a parameter. (That is, in DOM-compliant browsers, event objects are passed as parameters to event handlers, whether they are bound through DOM0 or DOM2 levels), At that time, in IE browser, if DOM0 level is used to specify the time handler, the event object is stored in event attribute of window, and if attachEvent () is used to specify the time handler, the event object is passed to the event handler as a parameter. There is a difference between the value in the DOM-compliant browser's event object and the value in the IE's event object. But they all have a common value-type (that is, the type of time triggered). In an DOM-compliant browser, the target attribute of an event object represents the target of the event. Take an click event as an example, and the target attribute refers to the most specific element. In the IE browser, the srcElement property of the event object represents the event target

In this case, I added an click event handler to the outermost div (whose id is warp). Determine the most specific node that triggers the event by judging the id value of the event target. If the id value of the event target is pre, switch to the previous picture, and if the id value of the event target is next, switch to the next picture. Event brokers are used here, which can reduce the memory used.

Function throttling is used in this case to reduce the computational effort of the browser when resize events are fired continuously, because if the browser is too computational, the browser will slow down or even crash. The main idea of function throttling is that when an event is triggered, in the event handler, the calculation is not done immediately, but setTimeout or setInterval is used to calculate after a specified time.

Setting timer and clearing timer will not be explained now because it is necessary to fully explain that timer also involves browser threads and single-threaded execution of js. The main reason is that I haven't fully understood it. The browser is multithreaded, the timer is started in the timer thread of the browser, and the js execution program is another thread of the browser. The browser has no other threads except these two threads. I will write another article after I understand the connection between browser threads.

In this example, the transparency of the picture is changed by setting the timer to gradually increase or decrease. Before increasing the opacity of the next image, reduce the opacity of the current image to 0.

Open the page to play automatically, which is also realized by timer. If you want to stop playing, clear the timer

The js code is as follows


//  When the page is loaded, add all the functions that need to be executed to the window Adj. load On the incident. What is used here is dom0 Class event, so you cannot bind for the window Adj. load Event addition   Multiple event handlers, so the method used is: first determine window.onload Is there a binding function? If it is bound, append the new function to the tail. If it is not bound, add it directly   Give it. Use attachEvent () or addEventListener () can be the same 1 The same of elements 1 Events are bound to multiple event handlers, so the following method can be avoided. 

function addLoadEvent(func){
 var oldLoad = window.onload;
 if(typeof oldLoad != 'function'){
 window.onload = func();
 }else{
 window.onload = function(){
  oldLoad();
  func();
 }
 }
}



// Settings class For list The height of , Because the picture's position For absolute So .list The height of the element is zero 
// If 1 The height of the parent element of the elements is 0 To set the margin: auto 0;  Doesn't work 
function setListHeight(){
 var list = document.getElementById('list');
 var imgItem = list.getElementsByTagName('img')[0];
 var height = imgItem.offsetHeight;
 var list = document.getElementById('list');
 list.style.height = height + 'px';
}

// Settings li You can use the hierarchy of css Settings 
function setLiIndex(){
 var list = document.getElementById('list');
 var li = list.getElementsByTagName('li');
 var liLen = li.length;
 for(var i = 0;i<liLen;i++){
 li[i].style.zIndex = liLen-i;
 }
}
var index = 1;//index Represents the currently displayed page ,index Yes 1 Global variables 
var timer;//  Timer identifier, which is required if you want to clear the timer 

// Cross-browser bound objects for events 
var untilEvent = {
 addEvent:function(element,type,hander){
 if(element.addEventListener){
  element.addEventListener(type,hander,false);
 }else if(element.attachEvent){
  element.attachEvent('on'+type,hander);
 }else{
  element['on'+type] = hander;
 }
 },
 getEvent:function(event){
 return event?event:window.event;
 },
 getTarget:function(event){
 return event.target||event.srcElement;
 }

};
function btnClick(){
 var warp = document.getElementById('warp');
 untilEvent.addEvent(warp,'click',function(event){
 var event = untilEvent.getEvent(event);
 var target = untilEvent.getTarget(event);
 switch(target.id){
  case 'pre': if(index == 1){// If the currently displayed picture is already the first 1 Picture, when clicking to switch to " Upper 1 Zhang " Button, the picture to be displayed is set to the last 1 A picture 
   index =3;
  }else{
   --index;
  }
  anmitate();
  break;
  case 'next':if(index == 3){// If the currently displayed picture is the last picture, click Switch to " Under 1 Zhang " Button, the picture to be displayed is set to the 1 A picture 
  index = 1;
  }else{
   ++index;
  }
  anmitate();
  break;
 }
 });
}
// Reduce the transparency of a picture 
function decline(cur,inverTime,inverOpacity){
 var opacityed = parseFloat(cur.style.opacity);
 if(opacityed > 0){
 cur.style.opacity = opacityed-inverOpacity;
 setTimeout(function(){
  decline(cur,inverTime,inverOpacity);
 },inverTime);
 }
}
// Function to toggle pictures 
function anmitate(){
 var list = document.getElementById('list');
 var imgs = list.getElementsByTagName('img');
 var imgsLen = imgs.length;
 var whole = 300;// Switch 1 Time for a picture 
 var inverTime = 5;// Time interval 
 var inverOpacity = 1/(whole/inverTime);
 for(var i = 0;i<imgsLen;i++){
 decline(imgs[i],inverTime,inverOpacity);
 }
 var go = function(){
 var opacityed = parseFloat(imgs[index - 1].style.opacity);
 if(opacityed < 1){
  imgs[index-1].style.opacity = opacityed + inverOpacity;
  setTimeout(go,inverTime);
 }
 };
 go();
}
// Turn on the automatic page switching function 
function play() {
 timer = setTimeout(function () {
 if(index == 3){
  index = 1;
 }else{
  ++index;
 }
 anmitate();
  play();
  //
 }, 3000);
}
// Stop switching function , When the mouse moves to the carousel, it cancels automatic switching, and when the mouse moves away from the carousel, it starts automatic switching again 
function stop() {
 clearTimeout(timer);
}

// To the outermost layer div Add event handlers for mouse removal and mouse movement 
function getWarp(){
 var warp = document.getElementById('warp');
 untilEvent.addEvent(warp,"mouseout",play);
 untilEvent.addEvent(warp,"mouseover",stop);
}
// Function throttles, when changing the window size, the size of the picture will change, so in order to make the control button in the middle of the vertical direction of the carousel, li The height of should change with the size of the picture 
function scrollEvent(){
 untilEvent.addEvent(window,"resize",function(){
 throttle(setListHeight);
 });
}
function throttle(method,context){
 clearTimeout(method.Tid);
 method.Tid = setTimeout(method,70);
}
addLoadEvent(scrollEvent);
addLoadEvent(setListHeight);
addLoadEvent(setLiIndex);
addLoadEvent(btnClick);
addLoadEvent(play);
addLoadEvent(getWarp);

Related articles: