mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-01-18 12:34:25 +08:00
fix(anchor): scroll
This commit is contained in:
parent
27dbdd517b
commit
79635958a5
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 () {
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
@ -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;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user