JavaScript slide下拉導航選單效果

admin發表於2018-12-30

現在的下拉導航選單都講究平滑優雅,粗暴的瞬間下拉的導航選單已經不多。

下面就通過程式碼例項介紹一下如何實現此種型別的效果,需要的朋友可以做一下參考。

程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!DOCTYPE html>
<html>
<head>
<meta charset=" utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style type="text/css">
* {
  margin: 0;
  padding: 0;
}
ul {
  list-style: none;
}
.box {
  width: 300px;
  margin: 10px;
  border: 1px solid #ccc;
  overflow: hidden;
  position: relative;
  font-size: 12px;
}
.oHx {
  height: 30px;
  background: #eee;
  line-height: 30px;
  font-size: 14px;
  text-indent: 14px;
  cursor: pointer;
}
.fold {
  position: absolute;
  top: 9px;
  right: 12px;
}
.box_content {
  line-height: 18px;
  overflow: hidden;
  display: none;
}
</style>
<script type="text/javascript">
function $(id) {
  return "string" == typeof id ? document.getElementById(id) : id;
}
 
function getElementsByClassName(className, id, tag) {
  tag = tag || "*";
  if (id) {
    var id = typeof id == "string" ? $(id) : id;
  }
  else {
    var id = document.body;
  }
  var els = id.getElementsByTagName(tag), arr = [];
  for (var index = 0, n = els.length; index < n; index++) {
    for (var j = 0, k = els[index].className.split(" "), l = k.length; j < l; j++) {
      if (k[j] == className) {
        arr.push(els[index]);
        break;
      }
    }
  }
  return arr;
};
 
function Slide(slideClass, slideBtn, slideCon, slideSpeed) {
  this.oSlides = getElementsByClassName(slideClass);
  this.oTimer = null;
  this.slideBtn = slideBtn;
  this.slideCon = slideCon;
  this.slideSpeed = slideSpeed;
}
Slide.prototype = {
  oTimer: null,
  _init: function () {
    this._slideEvent();
  },
  _slideEvent: function () {
    var This = this;
    for (var index = 0, n = This.oSlides.length; index < n; index++) {
      (function (n) {
        var oSlide = This.oSlides[n];
        var oSlideBtn = getElementsByClassName(This.slideBtn, oSlide)[0];
        var oSlideCon = getElementsByClassName(This.slideCon, oSlide)[0];
        oSlideBtn.onclick = function () {
          if (oSlideCon.style.display == "block" && This.oTimer == null) {
            This._slideClose(oSlideCon);
          }
          else if (!(oSlideCon.style.display == "block") && This.oTimer == null) {
            This._slideOpen(oSlideCon);
          }
        }
      })(index)
    }
  },
  _slideOpen: function (slideCon) {
    var This = this;
    slideCon.style.display = "block";
    slideCon.style.height = "auto";
    var slideHeight = slideCon.offsetHeight;
    slideCon.style.height = 0 + "px";
    This.oTimer = setInterval(function () {
      if (slideCon.offsetHeight < slideHeight) {
        slideCon.style.height = slideCon.offsetHeight + 2 + "px";
      }
      else {
        clearInterval(This.oTimer);
        This.oTimer = null;
      }
    }, This.slideSpeed);
  },
  _slideClose: function (slideCon) {
    var This = this;
    This.oTimer = setInterval(function () {
      if (slideCon.offsetHeight <= 0) {
        clearInterval(This.oTimer);
        slideCon.style.display = "none";
        This.oTimer = null;
      }
      else {
        slideCon.style.height = slideCon.offsetHeight - 2 + "px";
      }
    }, This.slideSpeed);
  }
}
window.onload = function () {
  var mySlide = new Slide("box", "slide", "box_content", 10);
  mySlide._slideEvent();
}
</script>
</head>
<body>
<div class="box">
  <div class="oHx slide">螞蟻部落一</div>
  <div class="box_content">
    <ul class="uft" style="padding:10px;">
      <li><a href="#" target="_blank">本站的url地址是www.softwhy.com。</a></li>
      <li><a href="#" target="_blank">只有努力奮鬥才會有美好的未來。</a></li>
      <li><a href="#" target="_blank">沒有人一開始就是高手必須要奮鬥</a></li>
      <li><a href="#" target="_blank">每一天都是新的必須要好好珍惜</a></li>
    </ul>
  </div>
</div>
<div class="box">
  <div class="oHx slide">螞蟻部落二</div>
  <div class="box_content">
    <ul class="uft" style="padding:10px;">
      <li><a href="#" target="_blank">本站的url地址是www.softwhy.com。</a></li>
      <li><a href="#" target="_blank">只有努力奮鬥才會有美好的未來。</a></li>
      <li><a href="#" target="_blank">沒有人一開始就是高手必須要奮鬥</a></li>
      <li><a href="#" target="_blank">每一天都是新的必須要好好珍惜</a></li>
    </ul>
  </div>
</div>
</body>
</html>

上面的程式碼實現了我們的要求,下面介紹一下它的實現過程。

一.程式碼註釋:

(1).function $(id) {

  return "string" == typeof id ? document.getElementById(id) : id;

},模擬實現了jquery的id選擇器,能夠返回具有指定id屬性值的元素物件。

(2).function getElementsByClassName(className, id, tag) {},此方法模擬實現getElementsByClassName()方法,因為內建的此方法具有瀏覽器相容性問題,可以參閱getElementsByClassName()方法一章節。

className引數規定class屬性值,id規定一個id屬性值或者一個元素物件,tag規定一個元素型別。

(3).tag = tag || "*",如果沒有傳遞元素型別,那麼就用星號,用來獲取所有型別的元素。

(4).if (id) {

  var id = typeof id == "string" ? $(id) : id;

}

else {

  var id = document.body;

}如果傳遞了id引數。

會首先判斷是否是一個字串,如果是一個字串就認為是一個元素的id屬性值,然後獲取對應的元素物件,如果不是字串就認為傳遞的是一個元素物件。如果沒有傳遞id引數,那麼將id賦值為body物件。

(5).var els = id.getElementsByTagName(tag), arr = [],獲取指定標籤型別元素集合和宣告一個空陣列。

(6).for (var index = 0, n = els.length; index < n; index++),遍歷集合中每一個元素。

(7).for (var j = 0, k = els[index].className.split(" "), l = k.length; j < l; j++) {

  if (k[j] == className) {

    arr.push(els[index]);

    break;

  }

},遍歷每一個元素。

然後獲取當前元素的每一個class屬性值,並判斷屬性值是否包含指定的樣式類名稱。

如果有則將此元素存入陣列。

(8).return arr,返回陣列。

(9).function Slide(slideClass, slideBtn, slideCon, slideSpeed) {

  this.oSlides = getElementsByClassName(slideClass);

  this.oTimer = null;

  this.slideBtn = slideBtn;

  this.slideCon = slideCon;

  this.slideSpeed = slideSpeed;

},建立一個建構函式(也可以認為是類)。

第一個引數規定class樣式類屬性值,第二個引數規定點選的標題元素所具有的class樣式類屬性值,第三個引數規定內容元素所具有的class樣式類屬性值,第四個引數規定動畫速度。

(10).Slide.prototype = {},重寫Slide的原型物件。

(11).oTimer: null,定時器函式的標識。

(12)._init: function () {

    this._slideEvent();

  },呼叫此方法可以進行初始化操作。

(13)._slideEvent: function () {},此方法能夠實現一些初始化操作,下面會介紹。

(14).var This = this,將當前物件的指標賦值給變數This。

(15).for (var index = 0, n = This.oSlides.length; index < n; index++){},遍歷集合中的每一個元素,在本例項中就是最外層的box(class屬性值)元素。

(16).(function (n) {  var oSlide = This.oSlides[n];

  var oSlideBtn = getElementsByClassName(This.slideBtn, oSlide)[0];

  var oSlideCon = getElementsByClassName(This.slideCon, oSlide)[0];

  oSlideBtn.onclick = function () {

    if (oSlideCon.style.display == "block" && This.oTimer == null) {

      This._slideClose(oSlideCon);

     }

     else if (!(oSlideCon.style.display == "block") && This.oTimer == null) {

       This._slideOpen(oSlideCon);

      }

    }

})(index),採用閉包的方式,為標題元素(在本例中就是class屬性值為oHx slide的元素)註冊onclick事件處理函式。

(17)._slideOpen: function (slideCon) {},實現選單的展開效果,引數是選單的容器(在本例中就是class屬性值為box_content的元素)。

(18).var This = this,將當前物件例項的指標賦值給變數This。

(19).slideCon.style.display = "block";

slideCon.style.height = "auto";

var slideHeight = slideCon.offsetHeight;

slideCon.style.height = 0 + "px";

這裡的目的是為了獲取元素的伸展時的高度。

首先要將其設定為顯示狀態,這時候我們才能夠使用offsetHeight獲取高度。

然後在將高度設定為0,也就是預設狀態是摺疊的。

(20).This.oTimer = setInterval(function () {

  if (slideCon.offsetHeight < slideHeight) {

    slideCon.style.height = slideCon.offsetHeight + 2 + "px";

  }

  else {

    clearInterval(This.oTimer);

    This.oTimer = null;

  }

}, This.slideSpeed)

當前高度高度小於slideHeight的時候,每執行一次當前高度就會增加2px。

否則就停止定時器函式的執行。

二.相關閱讀:

(1).className屬性可以參閱JavaScript className一章節。

(2).split()方法可以參閱JavaScript split()一章節。

(3).push()方法可以參閱JavaScript push()一章節。

(4).break可以參閱JavaScript break與continue一章節。

(5).prototype可以參閱javascript prototype原型一章節。

(6).offsetHeight可以參閱js offsetHeight屬性一章節。

(7).clearInterval()方法可以參閱clearInterval()一章節。

(8).removeClass()方法可以參閱jQuery removeClass()一章節。

相關文章