Chicken dish by learning the front garden renovation blog (add directory)

The content described below is to add a garden blog directory

  • You need to be compatible markdown and TinyMCE editor
  • Add to active heading style
  • Optional fixed position

If an error or inadequate, please correct me!

Optional configuration

catalog: {
    enable: true,
    position: 'left',
},
  • enable whether the deprecation
  • Fixed position directory location
    • left fixed to the left
    • the right side in right
    • sidebar 'fixed effect similar to article directories Nuggets effect'


Plug-in architecture

I put the article directory integration as a plugin to the project, the following is the basic structure of the plug-in, allowing you to sort out ideas on here.

import { pageName, userAgent, hasPostTitle, getClientRect, throttle } from '@tools'
const { enable, position } = opts.catalog

// 在这里写几个 func

function catalog() {
  if (conditions) return // 在入口处做一些基本的判断
  // 在这里执行上面的 func
}

export default catalog

import

  • pageName return to the current page name, if not the details page of the article is not necessary to execute code
  • userAgent returns the user client type, mobile terminal without having to Article Directory
  • hasPostTitle returns the title of the article the existence of the current article
  • getClientRect return position relative to the element of the browser viewport

Construction of html

Ideas: traversing blog Campus Essay content child elements DOM, regular expressions obtained by title, create a directory html elements, and add the anchor link. Since the non-markdown editor title no id, id needs to be added when traversing its value is the title. Non markdown title content editors may not be directly nested h123 tag, it can be slightly determination process.

function build() {
  let $catalogContainer = $(
    `<div id="catalog">
            <div class='catListTitle'><h3>目录</h3></div>
        </div>`
  )
  const $ulContainer = $('<ul></ul>')
  const titleRegExp = /^h[1-3]$/

  $('#cnblogs_post_body')
    .children()
    .each(function () {
      if (titleRegExp.test(this.tagName.toLowerCase())) {
        let id
        let text

        if (this.id !== '') {
          id = this.id
          text = this.childNodes.length === 2 ? this.childNodes[1].nodeValue : this.childNodes[0].nodeValue
        } else {
          if (this.childNodes.length === 2) {
            const value = this.childNodes[1].nodeValue
            text = value ? value : $(this.childNodes[1]).text()
          } else {
            const value = this.childNodes[0].nodeValue
            text = value ? value : $(this.childNodes[0]).text()
          }
          id = text.trim()
          $(this).attr('id', id)
        }

        const title = `
                            <li class='${this.nodeName.toLowerCase()}-list'>
                                <a href='#${id}'>${text}</a>
                            </li>
                        `

        $ulContainer.append(title)
      }
    })

  $($catalogContainer.append($ulContainer)).appendTo('#sideBar')
  setCatalogPosition()
}

Fixed directory

Next, the configuration according to the user's position, is fixed at the specified directory location.

function setCatalogPosition() {
  const actions = {
    sidebar: () => {
      setCatalogToggle()
    },
    left: () => {
      $('#catalog').addClass('catalog-sticky-left')
    },
    right: () => {
      $('#catalog').addClass('catalog-sticky-right')
    },
  }

  actions[position]()
}

You may adopt a more concise wording, considered here scalability, the use of such an approach.

Handling of fixed sidebar

When the directory is fixed to the sidebar, scroll to the original sidebar is not visible only display the directory location, is very simple, we only need to listen to scroll event, obtaining highly original sidebar, when it went off the screen fixed directory. Conversely, the opposite.

function setCatalogToggle() {
  if (position !== 'sidebar') return
  var p = 0,
    t = 0
  $(window).scroll(
    throttle(
      function () {
        const bottom = getClientRect(document.querySelector('#sideBarMain')).bottom
        if (bottom <= 0) {
          $('#catalog').addClass('catalog-sticky')
          p = $(this).scrollTop()
          t <= p ? $('#catalog').addClass('catalog-scroll-up') : $('#catalog').removeClass('catalog-scroll-up')
          setTimeout(function () {
            t = p
          }, 0)
        } else {
          $('#catalog').removeClass('catalog-sticky')
        }
      },
      50,
      1000 / 60
    )
  )
}

Add to active heading style

This step is the realization of ideas and processes in the case of fixed sidebar basically the same, when a article directory beyond the screen, we add the title to the corresponding active style on it.

function setActiveCatalogTitle() {
  $(window).scroll(
    throttle(
      function () {
        for (let i = $('#catalog ul li').length - 1; i >= 0; i--) {
          const titleId = $($('#catalog ul li')[i]).find('a').attr('href').replace(/[#]/g, '')
          const postTitle = document.querySelector(`#cnblogs_post_body [id='${titleId}']`)
          if (getClientRect(postTitle).top <= 10) {
            if ($($('#catalog ul li')[i]).hasClass('catalog-active')) return
            $($('#catalog ul li')[i]).addClass('catalog-active')
            $($('#catalog ul li')[i]).siblings().removeClass('catalog-active')
            return
          }
        }
      },
      50,
      1000 / 60
    )
  )
}

Project links

GZ/awescnb

Guess you like

Origin www.cnblogs.com/guangzan/p/12669090.html