Skip to content

Commit

Permalink
增加ABackTop组件,支持在自定义滚动容器
Browse files Browse the repository at this point in the history
  • Loading branch information
zhigang.li committed Nov 19, 2018
1 parent 39e8fa7 commit 853f3d3
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/components/main/components/a-back-top/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import ABackTop from './index.vue'
export default ABackTop
90 changes: 90 additions & 0 deletions src/components/main/components/a-back-top/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<template>
<div :class="classes" :style="styles" @click="back">
<slot>
<div :class="innerClasses">
<i class="ivu-icon ivu-icon-ios-arrow-up"></i>
</div>
</slot>
</div>
</template>
<script>
import { scrollTop } from '@/libs/util'
import { on, off } from '@/libs/tools'
const prefixCls = 'ivu-back-top'
export default {
name: 'ABackTop',
props: {
height: {
type: Number,
default: 400
},
bottom: {
type: Number,
default: 30
},
right: {
type: Number,
default: 30
},
duration: {
type: Number,
default: 1000
},
container: {
type: null,
default: window
}
},
data () {
return {
backTop: false
}
},
mounted () {
// window.addEventListener('scroll', this.handleScroll, false)
// window.addEventListener('resize', this.handleScroll, false)
on(this.containerEle, 'scroll', this.handleScroll)
on(this.containerEle, 'resize', this.handleScroll)
},
beforeDestroy () {
// window.removeEventListener('scroll', this.handleScroll, false)
// window.removeEventListener('resize', this.handleScroll, false)
off(this.containerEle, 'scroll', this.handleScroll)
off(this.containerEle, 'resize', this.handleScroll)
},
computed: {
classes () {
return [
`${prefixCls}`,
{
[`${prefixCls}-show`]: this.backTop
}
]
},
styles () {
return {
bottom: `${this.bottom}px`,
right: `${this.right}px`
}
},
innerClasses () {
return `${prefixCls}-inner`
},
containerEle () {
return this.container === window ? window : document.querySelector(this.container)
}
},
methods: {
handleScroll () {
this.backTop = this.containerEle.scrollTop >= this.height
},
back () {
let target = typeof this.container === 'string' ? this.containerEle : (document.documentElement || document.body)
const sTop = target.scrollTop
scrollTop(this.containerEle, sTop, 0, this.duration)
this.$emit('on-click')
}
}
}
</script>
5 changes: 4 additions & 1 deletion src/components/main/main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<keep-alive :include="cacheList">
<router-view/>
</keep-alive>
<ABackTop :height="100" :bottom="80" :right="50" container=".content-wrapper"></ABackTop>
</Content>
</Layout>
</Content>
Expand All @@ -38,6 +39,7 @@ import SideMenu from './components/side-menu'
import HeaderBar from './components/header-bar'
import TagsNav from './components/tags-nav'
import User from './components/user'
import ABackTop from './components/a-back-top'
import Fullscreen from './components/fullscreen'
import Language from './components/language'
import ErrorStore from './components/error-store'
Expand All @@ -56,7 +58,8 @@ export default {
TagsNav,
Fullscreen,
ErrorStore,
User
User,
ABackTop
},
data () {
return {
Expand Down
36 changes: 36 additions & 0 deletions src/libs/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,39 @@ export const localSave = (key, value) => {
export const localRead = (key) => {
return localStorage.getItem(key) || ''
}

// scrollTop animation
export const scrollTop = (el, from = 0, to, duration = 500, endCallback) => {
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = (
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
return window.setTimeout(callback, 1000 / 60)
}
)
}
const difference = Math.abs(from - to)
const step = Math.ceil(difference / duration * 50)

const scroll = (start, end, step) => {
if (start === end) {
endCallback && endCallback()
return
}

let d = (start + step > end) ? end : start + step
if (start > end) {
d = (start - step < end) ? end : start - step
}

if (el === window) {
window.scrollTo(d, d)
} else {
el.scrollTop = d
}
window.requestAnimationFrame(() => scroll(d, end, step))
}
scroll(from, to, step)
}

0 comments on commit 853f3d3

Please sign in to comment.