简易jquery博客页面目录树封装

本文介绍了一种使用jQuery封装的简易博客目录树插件,该插件能自动生成基于h2和h3标签的目录结构,通过设置不同的参数如高度、宽度、字体大小等,实现菜单的自定义样式,并在滚动页面时自动激活当前层级的目录项。

简易jquery博客目录树封装

说在前

  • jquery 1.12.4

效果展示

在这里插入图片描述

使用

<script type="text/javascript">
	// enable the page element had loaded
      $(function(){
        $('#menu').createMenu({
          levelOne: 'h2', 
          levelTwo: 'h3',
          offsetTop: 100, // offsetTop + scrollTop = the scale to trigger the active style
          containerPadding: 40, // the padding of the menu container padding
          height: 400, // menu container height
          width: 300, // menu containre width
          fontSize: 14,
          linePadding: 10, // each lineheight of the row in the menu
          containerTop: 50, // the position top of the menu container on the page 
          containerRight: 20 // the position right of the menu container on the page 
      	})
      })
</script>

代码

// javascript
(function($){

  let myMenu = (function(){

    let Plugin = function(element, options){
      this.element  = $(element) ;
      this.setting  = $.extend({}, $.fn.createMenu.defaults, typeof options === 'object'&&options) ;
      this.init() ;
    }

    Plugin.prototype  = {

      $preActiveNode: null,
      flag: true,

      init: function(){
        this.createHtml() ;
        this.setStyle() ;
        this.setActive() ;
        this.bindEvent() ;
        
      },

      // create the content the blog menu by the levelOne and the levelTwo
      createHtml: function(){
        let opts = this.setting ;
        // initial the style of the container

        let idIndex = 0 ;
        let $ul = $('<ul></ul>').addClass('mymenu-display') ;

        this.ul = $ul ;

        // traversing the content
        $('body *').each(function(){
          let ele = this ;
          if(ele.tagName === opts.levelOne.toUpperCase()){
            ele.setAttribute('id', idIndex) ;
            $ul.append($(`<li><a href="#${idIndex}">${ele.innerText}</a></li>`)) ;
            idIndex++ ;
          }else if(ele.tagName === opts.levelTwo.toUpperCase()){
            ele.setAttribute('id', idIndex) ;
            $ul.append($(`<li class="sub"><a href="#${idIndex}">${ele.innerText}</a></li>`)) ;
            idIndex++ ;
          }

        })

        if(Object.keys($ul.children()).length === 3 ){
          return this.continue = false ;
        }
        

        this.element.append($ul) ;

      },

      // set the css style
      setStyle: function(){

        let opts = this.setting ;
        let levelOne_font_size =  opts.fontSize+6 ;
        let levelTwo_font_size = opts.fontSize ;
        
        let height  = (typeof opts.height            === 'number' || typeof opts.height === 'string')&&opts.height ||309;
        let width   = (typeof opts.width             === 'number' || typeof opts.height === 'string')&&opts.width  ||200;
        let padding = (typeof opts.containerPadding  === 'number' || typeof opts.height === 'string')&&opts.containerPadding||20 ;
        let cTop    = (typeof opts.containerTop      === 'number' || typeof opts.containerTop === 'string')&&opts.containerTop||20 ;
        let cRight  = (typeof opts.containerRight    === 'number' || typeof opts.containerRight === 'string')&&opts.containerRight||20 ;

        
        this.element.css({
          'height': height,
          'width':width,
          'padding': padding,
          'overflow': 'auto',
          'max-width': '100%',
          'position': 'fixed',
          'right': cRight,
          'top': cTop
        })


        this.ul.children('li:not(.sub)').css({
          'font-size': levelOne_font_size,
        }).siblings('.sub').css({
          'font-size': levelTwo_font_size,
        }) ;
      },

      // set the active status
      setActive: function(ele){
        let $ele = $(ele) ;
        let id = $ele.attr('id') ;
        $ele = $ele.length === 0? $('.mymenu-display li:first-child'):$('.mymenu-display li').eq(id) ;
        $ele.addClass('active').siblings('.active').removeClass('active') ;
        this.element.stop().animate({
          'scrollTop': $ele.offset().top - this.ul.offset().top + this.setting.linePadding 
        }, 100)
      },

      // bind the event
      bindEvent: function(){
        let that = this ;
        let opts = that.setting ;
        let $titleTarget = $(`${opts.levelOne},${opts.levelTwo}`) ;

          $(window).scroll(function(e){
      
            let wsTop = $(this).scrollTop() ;


  
            let flag = true; 
            let $preNode = $titleTarget.eq(0) ;
            $titleTarget.each(function(){
              let $ele = $(this) ; 
              let eTop = $ele.offset().top ;
              if( wsTop + opts.offsetTop >= eTop ){
                  $preNode = $ele ;
                  flag = true ;
              }else if(flag && (wsTop + opts.offsetTop < eTop)){
                that.setActive($preNode) ;
                flag = false ;
              }
  
            })
  
          })



      },


    }

    return Plugin ;

  })() ;

  $.fn.createMenu = function(options){

    new myMenu(this, options) ;

  }


  /**
   * @params offsetTop: the distance of the element to trigger the event
   * @params padding: the padding of the menu area
   * @params height: the height of the menu content
   * @params width: the width of the mnu content
   */
  $.fn.createMenu.defaults = {
    levelOne: 'h2',
    levelTwo: 'h3',
    offsetTop: 100 ,
    containerPadding: 40,
    height: 400,
    width: 300,
    fontSize: 14,
    linePadding: 10,
    containerTop: 50,
    containerRight: 20
  }

}
)(jQuery) ;

代码简析

  • 原型链

jQuery.fn === jQuery.prototype

  • 设置默认值
  $.fn.createMenu.defaults = {
    levelOne: 'h2',
    levelTwo: 'h3',
    offsetTop: 100 ,
    containerPadding: 40,
    height: 400,
    width: 300,
    fontSize: 14,
    linePadding: 10,
    containerTop: 50,
    containerRight: 20
  }
  • 事件绑定到原型链上
  $.fn.createMenu = function(options){

    new myMenu(this, options) ;

  }
  • 参数继承:缺省时使用默认值,无缺省使用自定义的值
 this.setting  = $.extend({}, $.fn.createMenu.defaults, typeof options === 'object'&&options) ;

/* css */
.mymenu-display{
  list-style: none;
  color: grey;
  position: relative;
  background: white;
  border: 1px solid #8080804f;
  border-radius: 10px;
}

.mymenu-display li{

  padding: 10px 20px;
}

.mymenu-display .active{
  color: black;
  font-weight: 600;
}

.mymenu-display a{
  position: static;
  text-decoration: none;
  color: inherit;
  display: block;
  width: 100%;
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值