fix(anchor): scroll

This commit is contained in:
07akioni 2019-10-13 21:13:32 +08:00
parent 27dbdd517b
commit 79635958a5
5 changed files with 59 additions and 12 deletions

View File

@ -34,14 +34,15 @@ export default {
container: null, container: null,
stickToTop: false, stickToTop: false,
stickToBottom: false, stickToBottom: false,
memorizedTop: null memorizedTop: null,
affixTop: null
} }
}, },
computed: { computed: {
style () { style () {
const style = {} const style = {}
if (this.affixed && this.memorizedTop !== null) { if (this.affixed && this.affixTop !== null) {
style.top = `${this.memorizedTop}px` style.top = `${this.affixTop}px`
} }
return style return style
}, },
@ -51,6 +52,7 @@ export default {
}, },
mounted () { mounted () {
this.init() this.init()
this.memorizeTop()
}, },
beforeDestroy () { beforeDestroy () {
if (this.container) { if (this.container) {
@ -68,6 +70,12 @@ export default {
this.container.addEventListener('scroll', this.handleScroll) this.container.addEventListener('scroll', this.handleScroll)
} }
}, },
memorizeTop () {
const {
top
} = this.$el.getBoundingClientRect()
this.memorizedTop = top
},
handleScroll (e) { handleScroll (e) {
const containerEl = this.container.nodeName === '#document' ? this.container.documentElement : this.container const containerEl = this.container.nodeName === '#document' ? this.container.documentElement : this.container
let scrollTop = containerEl.scrollTop let scrollTop = containerEl.scrollTop
@ -84,12 +92,11 @@ export default {
this.stickToBottom = false this.stickToBottom = false
} }
if (!originalAffixed && this.affixed) { if (!originalAffixed && this.affixed) {
let {
top
} = this.$el.getBoundingClientRect()
// console.log(e, this.$el.getBoundingClientRect().top) // console.log(e, this.$el.getBoundingClientRect().top)
this.memorizedTop = top this.affixTop = this.memorizedTop
// debugger // debugger
} else {
this.memorizeTop()
} }
} }
} }

View File

@ -13,6 +13,9 @@
<div <div
ref="bar" ref="bar"
class="n-anchor-rail__bar" class="n-anchor-rail__bar"
:class="{
'n-anchor-rail__bar--active': activeHref !== null
}"
/> />
</div> </div>
<slot /> <slot />
@ -31,6 +34,7 @@ function getOffsetTop (el, container) {
const { const {
top: containerTop top: containerTop
} = container.getBoundingClientRect() } = container.getBoundingClientRect()
// console.log('elTop', elTop, 'containerTop', containerTop)
return elTop - containerTop return elTop - containerTop
} }
@ -41,6 +45,10 @@ export default {
target: { target: {
type: Function, type: Function,
default: null default: null
},
bound: {
type: Number,
default: 12
} }
}, },
data () { data () {
@ -50,6 +58,20 @@ export default {
container: null container: null
} }
}, },
watch: {
activeHref (value) {
if (value === null) {
const slotEl = this.$refs.slot
slotEl.style.maxWidth = `0px`
const barEl = this.$refs.bar
window.setTimeout(() => {
slotEl.style.top = null
barEl.style.top = null
// slotEl.style.top = null
}, 150)
}
}
},
mounted () { mounted () {
this.init() this.init()
}, },
@ -84,8 +106,20 @@ export default {
}, },
setActiveHref (href) { setActiveHref (href) {
this.activeHref = href this.activeHref = href
const idMatchResult = /#([^#]+)$/.exec(href)
if (idMatchResult) {
const linkEl = document.getElementById(idMatchResult[1])
if (linkEl) {
const top = getOffsetTop(linkEl, this.container) + (this.container.scrollTop || 0)
this.container.scrollTo({
top: top - this.bound
})
// this.handleScroll()
}
}
}, },
handleScroll () { handleScroll () {
console.log('handleScroll')
const links = [] const links = []
this.collectedLinkHrefs.forEach(href => { this.collectedLinkHrefs.forEach(href => {
const idMatchResult = /#([^#]+)$/.exec(href) const idMatchResult = /#([^#]+)$/.exec(href)
@ -105,8 +139,8 @@ export default {
// const containerScrollTop = this.container.scrollTop // const containerScrollTop = this.container.scrollTop
// console.log(links) // console.log(links)
const activeLink = links.reduce((prevLink, link) => { const activeLink = links.reduce((prevLink, link) => {
// console.log(link.top) console.log(link.top)
if (link.top < 5) { if (link.top <= this.bound) {
if (prevLink === null) { if (prevLink === null) {
return link return link
} else if (link.top > prevLink.top) { } else if (link.top > prevLink.top) {
@ -119,6 +153,8 @@ export default {
}, null) }, null)
if (activeLink) { if (activeLink) {
this.activeHref = activeLink.href this.activeHref = activeLink.href
} else {
this.activeHref = null
} }
}, },
init () { init () {

View File

@ -30,7 +30,11 @@
left: 0; left: 0;
transition: top .15s $default-cubic-bezier, background-color .3s $default-cubic-bezier; transition: top .15s $default-cubic-bezier, background-color .3s $default-cubic-bezier;
width: 4px; width: 4px;
background-color: $--primary-6; height: 21px;
background-color: transparent;
@include m(active) {
background-color: $--primary-6;
}
} }
& + { & + {
@include b(anchor-link) { @include b(anchor-link) {

View File

@ -1,3 +1,3 @@
@mixin setup-dark-anchor { @mixin setup-dark-anchor {
$--anchor-rail-background-color: rgba(255, 255, 255, .15) !global; $--anchor-rail-background-color: #404555 !global;
} }

View File

@ -1,3 +1,3 @@
@mixin setup-light-anchor { @mixin setup-light-anchor {
$--anchor-rail-background-color: rgba(0, 0, 0, .15) !global; $--anchor-rail-background-color: #d9d9d9 !global;
} }