10分鐘重溫JS原生手寫輪播圖

手寫一個原生輪播圖

  • 被框架限制過久,不少簡單的功能都用框架了,可是框架有他的侷限性,這時候原生JS手寫一個小功能就很香了,可是過久沒用,又有些忘記了,因此今天打算手寫一個輪播圖,複習一下原生js的使用,和輪播圖用到的思想
  • 咱們再來重溫一下輪播的實現原理,用一個展現圖片的盒子這個盒子固定一張圖片大小,超出隱藏,把圖片橫向排列,朝一個方向移動,每次移動一張圖片的距離,這樣,雖然頁面是一個擁有多張圖片的超長集合圖片,可是每次用戶看到的都是一張完整的圖片,咱們須要作的就是用定時器控制圖片移動的時間和距離,點擊按鈕同理

第一步:構建頁面文檔

<div class="all" id='box'>
 <!-- 圖片 -->  <div class="screen">  <ul>  <li><img src="./lunboimage/timg1.jpg" width="500" height="200"></li>  <li><img src="./lunboimage/timg2.jpg" width="500" height="200"></li>  <li><img src="./lunboimage/timg3.jpg" width="500" height="200"></li>  <li><img src="./lunboimage/timg4.jpg" width="500" height="200"></li>  <li><img src="./lunboimage/timg5.jpg" width="500" height="200"></li>  <li><img src="./lunboimage/timg1.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> 複製代碼

小結:分爲三個部分,輪播區域,頁碼區域,左右箭頭區域markdown

第二部:樣式區域

* {
 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: 0;  /*要足夠寬才放到一行裏*/  width: 3000px;  }   .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 {  /*距離父元素右邊5像素*/  right: 5px;  /*表明把left的值清空(設置爲默認值)*/  left: auto;  } 複製代碼

小結:首先 初始化樣式,而後讓頁面中5張圖片橫向排列,而後將展現圖片那個盒子設置overflow:hidden,超出隱藏,這樣就只能恰好看到一張圖片,剩下的被隱藏了,框架

重點部分 :功能實現(分步代碼)

  • 準備工做:
//1 找到大盒子
 var box = document.querySelector('#box');  //2 找到箭頭  var arr = document.querySelector('#arr');  //3 找到ul  var ul = document.querySelector('ul');  //4 找到放圖片的div的寬度  var screenW = document.querySelector('.screen').offsetWidth;  //5. 找到ol下面的全部li(也就是找到全部頁碼)  var pageList = document.querySelectorAll('ol>li'); 複製代碼

小結:這裏使用dom的document類型的節點獲取頁面節點元素,分別找到了盒子,左右箭頭和放置圖片的盒子,以及他的寬度,還有全部頁碼的集合dom

  • 功能實現函數
//1 移動動畫封裝函數 參數1,移動的目標,參數2,移動的距離
 function animate(obj, target) {  // 每次先中止上一個計時器  clearInterval(obj.timerID);  obj.timerID = setInterval(function() {  // 得到它當前位置 要求子元素和父級元素都要定位(切記)  var current = obj.offsetLeft;  // 移動距離減去當前距離,每次前進10px,直到到達,到達後中止定時器  if (Math.abs(target - current) > 10) {  // 走一步  current += target > current ? 10 : -10;  // 賦值給left  obj.style.left = current + "px";  } else {  obj.style.left = target + "px";  }  if (current == target) {  clearInterval(obj.timerID);  }  }, 10);  };  //2 下一頁的函數  function nextPage() {  // 在下一頁點擊事件裏作個判斷,若是是最後一張,就閃現到第一張下標0的那張  if (index == ul.children.length - 1) {  index = 0;  ul.style.left = 0;  }  // 到達後頁碼++  index++;  // 用最新的目標下標*寬度賦值給ul current = -index * screenW;  // 參數1:移動哪一個元素 參數2:目標位置  animate(ul, -index * screenW);  // 先讓全部頁碼去掉高亮  for (var i = 0; i < pageList.length; i++) {  pageList[i].className = "";  }  // 若是是最後一張(看起來是第一張的那張圖片)  if (index == ul.children.length - 1) {  //就讓下標0的頁碼高亮  pageList[0].className = "current";  } else {  // 還要當前顯示第幾個圖片,就讓第幾個頁碼高亮  pageList[index].className = "current";  }  }  //3 遍歷全部頁碼給它們加點擊事件  for (var i = 0; i < pageList.length; i++) {  // 先把下標存到每一個頁碼身上  pageList[i].setAttribute('index', i);  pageList[i].onclick = function() {  // 一開始判斷,若是當前圖片是最後一頁,就閃現到第一頁  if (index == ul.children.length - 1) {  index = 0;  ul.style.left = 0;  }  //獲取被點擊的頁碼的下標  var idx = this.getAttribute('index');  // 若是你當前是第一頁,而且點擊的是最後一個頁碼  if (index == 0 && idx == pageList.length - 1) {  //閃現到最後一頁  index = ul.children.length - 1;  ul.style.left = -index * screenW + "px";  }  // 點哪一個下標的頁碼就讓對應的圖片到對應的下標去  animate(ul, -idx * screenW);  // 還要讓記錄圖片下標的index更新成對應的下標  index = idx;  //排他去掉高亮  for (var j = 0; j < pageList.length; j++) {  pageList[j].className = "";  }  this.className = "current";  }  } 複製代碼

小結:這一步首先是一個動畫效果函數,他的第一個參數是對象,第二個是目標移動距離,因此移動時先中止計時器。而後計算移動位子,在移動到時先中止,等待下一個計時器開始,,下一頁函數就是調用動畫效果函數,用第幾頁對應的index乘寬度,獲得最新座標,傳給動畫函數,這裏要注意一個最後一張和第一張的狀況,而後遍歷全部頁碼,給他添加點擊事件,點哪一張就到哪一張下標,而後排他去除樣式,給當前高亮,函數

  • 效果功能
var timerID = setInterval(nextPage, 2200);
 //1 大盒子鼠標移入:中止計時器,頁面中止運動  box.onmouseover = function() {  //左右點擊按鈕隱藏  arr.style.display = "block";  //中止計時器  clearInterval(timerID);  }  //2 大盒子鼠標移出:開始計時器,頁面開始運動  box.onmouseout = function() {  arr.style.display = "none";  timerID = setInterval(nextPage, 2200);  }  // 準備一個變量index,默認從0開始,由於默認顯示下標0的圖片  var index = 0;  //3 下一頁的點擊事件:調用下一頁事件  document.getElementById('right').onclick = function() {  nextPage();  };  //4 完成上一頁點擊事件  document.getElementById('left').onclick = function() {  // 在上一頁點擊事件裏作個判斷,若是是第一張,就閃現到最後一張,而後再上一張  if (index == 0) {  //閃現到最後一張(也就是看起來內容是第一張的圖片,下標是長度-1)  index = ul.children.length - 1;  ul.style.left = -index * screenW + "px";  }  index--;  animate(ul, -index * screenW);  //排他,全部樣式取消  for (var i = 0; i < pageList.length; i++) {  pageList[i].className = "";  }  // 圖片是下標幾,就取出下標幾的頁碼  pageList[index].className = "current";  }; 複製代碼

小結:思考邏輯,調用上面實現的代碼,實現功能oop

功能實現(完整代碼)

//!!!!!!!!!!!!!!!首先 準備工做!!!!!!!!!!!!
  //1 找到大盒子  var box = document.querySelector('#box');  //2 找到箭頭  var arr = document.querySelector('#arr');  //3 找到ul  var ul = document.querySelector('ul');  //4 找到放圖片的div的寬度  var screenW = document.querySelector('.screen').offsetWidth;  //5. 找到ol下面的全部li(也就是找到全部頁碼)  var pageList = document.querySelectorAll('ol>li');   //!!!!!!!!!!!!!!!!!!!!!!!!!其次,功能實現函數!!!!!!!!!!!!!!!!!!!!!   //1 移動動畫封裝函數 參數1,移動的目標,參數2,移動的距離  function animate(obj, target) {  // 每次先中止上一個計時器  clearInterval(obj.timerID);  obj.timerID = setInterval(function() {  // 得到它當前位置 要求子元素和父級元素都要定位(切記)  var current = obj.offsetLeft;  // 移動距離減去當前距離,有多說明沒到,每次前進10px,直到到達,到達後中止定時器  if (Math.abs(target - current) > 10) {  // 走一步  current += target > current ? 10 : -10;  // 賦值給left  obj.style.left = current + "px";  } else {  obj.style.left = target + "px";  }  if (current == target) {  clearInterval(obj.timerID);  }  }, 10);  };  //2 下一頁的函數  function nextPage() {  // 在下一頁點擊事件裏作個判斷,若是是最後一張,就閃現到第一張下標0的那張  if (index == ul.children.length - 1) {  index = 0;  ul.style.left = 0;  }  // 讓index++  index++;  // 用最新的-下標*寬度賦值給ul  // var current = -index * screenW;  // ul.style.left = current + "px";  // 參數1:移動哪一個元素  // 參數2:目標位置  animate(ul, -index * screenW);  // 先讓全部頁碼去掉高亮  for (var i = 0; i < pageList.length; i++) {  pageList[i].className = "";  }  // 若是是最後一張(看起來是第一張的那張圖片)  if (index == ul.children.length - 1) {  //就讓下標0的頁碼高亮  pageList[0].className = "current";  } else {  // 還要當前顯示第幾個圖片,就讓第幾個頁碼高亮  pageList[index].className = "current";  }  }  //3 遍歷全部頁碼給它們加點擊事件  for (var i = 0; i < pageList.length; i++) {  // 先把下標存到每一個頁碼身上  pageList[i].setAttribute('index', i);  pageList[i].onclick = function() {  // 一開始判斷,若是當前圖片是最後一頁,就閃現到第一頁  if (index == ul.children.length - 1) {  index = 0;  ul.style.left = 0;  }  //獲取被點擊的頁碼的下標  var idx = this.getAttribute('index');  // 若是你當前是第一頁,而且點擊的是最後一個頁碼  if (index == 0 && idx == pageList.length - 1) {  //閃現到最後一頁  index = ul.children.length - 1;  ul.style.left = -index * screenW + "px";  }  // 點哪一個下標的頁碼就讓對應的圖片到對應的下標去  animate(ul, -idx * screenW);  // 還要讓記錄圖片下標的index更新成對應的下標  index = idx;  //排他去掉高亮  for (var j = 0; j < pageList.length; j++) {  pageList[j].className = "";  }  this.className = "current";  }  }   //!!!!!!!!!!!!!!效果調用功能!!!!!!!!!!!  var timerID = setInterval(nextPage, 2200);  //1 大盒子鼠標移入:中止計時器,頁面中止運動  box.onmouseover = function() {  //左右點擊按鈕隱藏  arr.style.display = "block";  //中止計時器  clearInterval(timerID);  }  //2 大盒子鼠標移出:開始計時器,頁面開始運動  box.onmouseout = function() {  arr.style.display = "none";  timerID = setInterval(nextPage, 2200);  }  // 準備一個變量index,默認從0開始,由於默認顯示下標0的圖片  var index = 0;  //3 下一頁的點擊事件:調用下一頁事件  document.getElementById('right').onclick = function() {  nextPage();  };  //4 完成上一頁點擊事件  document.getElementById('left').onclick = function() {  // 在上一頁點擊事件裏作個判斷,若是是第一張,就閃現到最後一張,而後再上一張  if (index == 0) {  //閃現到最後一張(也就是看起來內容是第一張的圖片,下標是長度-1)  index = ul.children.length - 1;  ul.style.left = -index * screenW + "px";  }  index--;  animate(ul, -index * screenW);  //排他,全部樣式取消  for (var i = 0; i < pageList.length; i++) {  pageList[i].className = "";  }  // 圖片是下標幾,就取出下標幾的頁碼  pageList[index].className = "current";  }; 複製代碼

本文使用 mdnice 排版動畫

相關文章
相關標籤/搜索