12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- const vueSticky = {}
- let listenAction
- vueSticky.install = Vue => {
- Vue.directive('sticky', {
- inserted(el, binding) {
- const params = binding.value || {}
- const stickyTop = params.stickyTop || 0
- const zIndex = params.zIndex || 1000
- const elStyle = el.style
- elStyle.position = '-webkit-sticky'
- elStyle.position = 'sticky'
- // if the browser support css sticky(Currently Safari, Firefox and Chrome Canary)
- // if (~elStyle.position.indexOf('sticky')) {
- // elStyle.top = `${stickyTop}px`;
- // elStyle.zIndex = zIndex;
- // return
- // }
- const elHeight = el.getBoundingClientRect().height
- const elWidth = el.getBoundingClientRect().width
- elStyle.cssText = `top: ${stickyTop}px; z-index: ${zIndex}`
- const parentElm = el.parentNode || document.documentElement
- const placeholder = document.createElement('div')
- placeholder.style.display = 'none'
- placeholder.style.width = `${elWidth}px`
- placeholder.style.height = `${elHeight}px`
- parentElm.insertBefore(placeholder, el)
- let active = false
- const getScroll = (target, top) => {
- const prop = top ? 'pageYOffset' : 'pageXOffset'
- const method = top ? 'scrollTop' : 'scrollLeft'
- let ret = target[prop]
- if (typeof ret !== 'number') {
- ret = window.document.documentElement[method]
- }
- return ret
- }
- const sticky = () => {
- if (active) {
- return
- }
- if (!elStyle.height) {
- elStyle.height = `${el.offsetHeight}px`
- }
- elStyle.position = 'fixed'
- elStyle.width = `${elWidth}px`
- placeholder.style.display = 'inline-block'
- active = true
- }
- const reset = () => {
- if (!active) {
- return
- }
- elStyle.position = ''
- placeholder.style.display = 'none'
- active = false
- }
- const check = () => {
- const scrollTop = getScroll(window, true)
- const offsetTop = el.getBoundingClientRect().top
- if (offsetTop < stickyTop) {
- sticky()
- } else {
- if (scrollTop < elHeight + stickyTop) {
- reset()
- }
- }
- }
- listenAction = () => {
- check()
- }
- window.addEventListener('scroll', listenAction)
- },
- unbind() {
- window.removeEventListener('scroll', listenAction)
- }
- })
- }
- export default vueSticky
|