# All files / src Affix.vue

0% Statements 0/26
0% Branches 0/18
0% Functions 0/10
0% Lines 0/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71

     <template>
      <div class="hidden-print hidden-xs hidden-sm">
        <nav class="bs-docs-sidebar" :class="{affix:affixed}" :style="{marginTop:top}">
          <slot></slot>
        </nav>
      </div>
    </template>

    <script>
    import {toNumber} from './utils/utils.js'
    import $ from './utils/NodeList.js'

    export default {
      props: {
        offset: {
          type: Number,
          default: 0
        }
      },
      data () {
        return {
          affixed:false
        }
      },
      computed: {
        offsetNumber() {
          return toNumber(this.offset)
        },
        top () {
          return this.offsetNumber > 0 ? this.offsetNumber + 'px' : null
        }
      },
      methods: {
        // from https://github.com/ant-design/ant-design/blob/master/components/affix/index.jsx#L20
        checkScroll () {
          // if is hidden don't calculate anything
          if (!(this.$el.offsetWidth || this.$el.offsetHeight || this.$el.getClientRects().length)) { return }
          // get window scroll and element position to detect if have to be normal or affixed
          let scroll = {}
          let element = {}
          const rect = this.$el.getBoundingClientRect()
          const body = document.body;
          ['Top','Left'].forEach(type => {
            let t = type.toLowerCase()
            let ret = window['page' + (type==='Top' ? 'Y' : 'X') + 'Offset']
            const method = 'scroll' + type
            if (typeof ret !== 'number') {
              // ie6,7,8 standard mode
              ret = document.documentElement[method]
              if (typeof ret !== 'number') {
                // quirks mode
                ret = document.body[method]
              }
            }
            scroll[t] = ret
            element[t] = scroll[t] + rect[t] - (this.$el['client'+type] || body['client'+type] || 0)
          })
          let fix = scroll.top > element.top - this.offsetNumber
          if (this.affixed !== fix) { this.affixed = fix }
        }
      },
      mounted () {
        $(window).on('scroll resize', () => this.checkScroll())
        setTimeout(() => this.checkScroll(), 0)
      },
      beforeDestroy () {
        $(window).off('scroll resize', () => this.checkScroll())
      }
    }
    </script>