因此,我的目标是使用 Nuxt.js 创建一个锚链接菜单,该菜单滚动到用户单击的页面部分,现在我有几种不同的方法,但我不确定哪个是“正确的”。
选项1:
我创建了一个菜单,该菜单获取offsetTop
部分 div 以了解当用户单击菜单中的链接时滚动多远,但我遇到的问题是 div 的值很少,例如当我推送时会发生offsetHeight
变化offsetTop
项目到服务器,我不确定是什么原因造成的。结果导致链接滚动到错误的位置并且无法正常工作。
注意:我尝试用价值和问题部分交换位置,之后效果很好,但我仍然需要在问题之上有价值部分。
在这里,我使用 created() 来获取值并将它们设置为 Vuex 状态,并在菜单所在的另一个组件及其所有功能中使用这些值:
var elements = [
{name: 'Intro', el: document.getElementById('intro')},
{name: 'About', el: document.getElementById('about')},
{name: 'Process', el: document.getElementById('process')},
{name: 'Value', el: document.getElementById('value')},
{name: 'Problem', el: document.getElementById('problem')},
{name: 'Contact', el: document.getElementById('contact')}
]
var bodyScrollTop = document.body.scrollTop
elements.forEach((element) => {
console.log(element)
var name = element.name
var el = element.el
var posTop = el.offsetTop - bodyScrollTop
var elementHeight = el.offsetHeight
var posBottom = posTop + elementHeight
this.$store.state.windows.forEach((window) => {
if(window.id == name) {
window.posTop = posTop
window.posBottom = posBottom
console.log('PosTop', window.id, window.posTop)
console.log('PosBottom', window.id, window.posBottom)
}
})
})
我使用 window.scrollTo() 滚动到该部分:
if (process.client) {
window.scrollTo({
top: position,
left: 0,
behavior: 'smooth'
});
}
这是本地机器上具有正确值的 div 规范:
accessKey: ""
align: ""
ariaAtomic: null
ariaAutoComplete: null
ariaBusy: null
ariaChecked: null
ariaColCount: null
ariaColIndex: null
ariaColSpan: null
ariaCurrent: null
ariaDescription: null
ariaDisabled: null
ariaExpanded: null
ariaHasPopup: null
ariaHidden: null
ariaKeyShortcuts: null
ariaLabel: null
ariaLevel: null
ariaLive: null
ariaModal: null
ariaMultiLine: null
ariaMultiSelectable: null
ariaOrientation: null
ariaPlaceholder: null
ariaPosInSet: null
ariaPressed: null
ariaReadOnly: null
ariaRelevant: null
ariaRequired: null
ariaRoleDescription: null
ariaRowCount: null
ariaRowIndex: null
ariaRowSpan: null
ariaSelected: null
ariaSetSize: null
ariaSort: null
ariaValueMax: null
ariaValueMin: null
ariaValueNow: null
ariaValueText: null
assignedSlot: null
attributeStyleMap: StylePropertyMap {size: 0}
attributes: NamedNodeMap {0: id, 1: class, 2: data-v-2a183b29, id: id, class: class, data-v-2a183b29: data-v-2a183b29, length: 3}
autocapitalize: ""
autofocus: false
baseURI: "http://localhost:3000/"
childElementCount: 2
childNodes: NodeList(3) [div.sidebar-content, text, div.section-content.problem-content]
children: HTMLCollection(2) [div.sidebar-content, div.section-content.problem-content]
classList: DOMTokenList(2) ['section', 'problem', value: 'section problem']
className: "section problem"
clientHeight: 766
clientLeft: 0
clientTop: 0
clientWidth: 1290
contentEditable: "inherit"
dataset: DOMStringMap {v-2a183b29: ''}
dir: ""
draggable: false
elementTiming: ""
enterKeyHint: ""
firstChild: div.sidebar-content
firstElementChild: div.sidebar-content
hidden: false
id: "problem"
innerHTML: "..."
innerText: "..."
inputMode: ""
isConnected: true
isContentEditable: false
lang: ""
lastChild: div.section-content.problem-content
lastElementChild: div.section-content.problem-content
localName: "div"
namespaceURI: "http://www.w3.org/1999/xhtml"
nextElementSibling: div#contact.section.contact
nextSibling: text
nodeName: "DIV"
nodeType: 1
nodeValue: null
nonce: ""
offsetHeight: 766
offsetLeft: 0
offsetParent: div.v-application--wrap
offsetTop: 3390
offsetWidth: 1290
onabort: null
onanimationend: null
onanimationiteration: null
onanimationstart: null
onauxclick: null
onbeforecopy: null
onbeforecut: null
onbeforepaste: null
onbeforexrselect: null
onblur: null
oncancel: null
oncanplay: null
oncanplaythrough: null
onchange: null
onclick: null
onclose: null
oncontextmenu: null
oncopy: null
oncuechange: null
oncut: null
ondblclick: null
ondrag: null
ondragend: null
ondragenter: null
ondragleave: null
ondragover: null
ondragstart: null
ondrop: null
ondurationchange: null
onemptied: null
onended: null
onerror: null
onfocus: null
onformdata: null
onfullscreenchange: null
onfullscreenerror: null
ongotpointercapture: null
oninput: null
oninvalid: null
onkeydown: null
onkeypress: null
onkeyup: null
onload: null
onloadeddata: null
onloadedmetadata: null
onloadstart: null
onlostpointercapture: null
onmousedown: null
onmouseenter: null
onmouseleave: null
onmousemove: null
onmouseout: null
onmouseover: null
onmouseup: null
onmousewheel: null
onpaste: null
onpause: null
onplay: null
onplaying: null
onpointercancel: null
onpointerdown: null
onpointerenter: null
onpointerleave: null
onpointermove: null
onpointerout: null
onpointerover: null
onpointerrawupdate: null
onpointerup: null
onprogress: null
onratechange: null
onreset: null
onresize: null
onscroll: null
onsearch: null
onseeked: null
onseeking: null
onselect: null
onselectionchange: null
onselectstart: null
onstalled: null
onsubmit: null
onsuspend: null
ontimeupdate: null
ontoggle: null
ontouchcancel: null
ontouchend: null
ontouchmove: null
ontouchstart: null
ontransitioncancel: null
ontransitionend: null
ontransitionrun: null
ontransitionstart: null
onvolumechange: null
onwaiting: null
onwebkitanimationend: null
onwebkitanimationiteration: null
onwebkitanimationstart: null
onwebkitfullscreenchange: null
onwebkitfullscreenerror: null
onwebkittransitionend: null
onwheel: null
outerHTML: "..."
ownerDocument: document
parentElement: div#cridty
parentNode: div#cridty
part: DOMTokenList [value: '']
prefix: null
previousElementSibling: div#value.section.value
previousSibling: text
scrollHeight: 766
scrollLeft: 0
scrollTop: 0
scrollWidth: 1290
shadowRoot: null
slot: ""
spellcheck: true
style: CSSStyleDeclaration {accentColor: '', additiveSymbols: '', alignContent: '', alignItems: '', alignSelf: '', …}
tabIndex: -1
tagName: "DIV"
textContent: "..."
title: ""
translate: true
virtualKeyboardPolicy: ""
[[Prototype]]: HTMLDivElem
这是菜单组件中本地计算机上使用的 scroll() 函数的对象,用于定义滚动的位置以及链接何时处于活动状态以及何时不处于活动状态:
active: (…)
hash: (…)
id: (…)
posBottom: 4128
posTop: 3385
这是 Ubuntu 服务器上的 div 规格,其值已更改:
accessKey: ""
align: ""
ariaAtomic: null
ariaAutoComplete: null
ariaBusy: null
ariaChecked: null
ariaColCount: null
ariaColIndex: null
ariaColSpan: null
ariaCurrent: null
ariaDescription: null
ariaDisabled: null
ariaExpanded: null
ariaHasPopup: null
ariaHidden: null
ariaKeyShortcuts: null
ariaLabel: null
ariaLevel: null
ariaLive: null
ariaModal: null
ariaMultiLine: null
ariaMultiSelectable: null
ariaOrientation: null
ariaPlaceholder: null
ariaPosInSet: null
ariaPressed: null
ariaReadOnly: null
ariaRelevant: null
ariaRequired: null
ariaRoleDescription: null
ariaRowCount: null
ariaRowIndex: null
ariaRowSpan: null
ariaSelected: null
ariaSetSize: null
ariaSort: null
ariaValueMax: null
ariaValueMin: null
ariaValueNow: null
ariaValueText: null
assignedSlot: null
attributeStyleMap: StylePropertyMap {size: 0}
attributes: NamedNodeMap {0: id, 1: class, 2: data-v-dcd49e84, id: id, class: class, data-v-dcd49e84: data-v-dcd49e84, length: 3}
autocapitalize: ""
autofocus: false
baseURI: "..."
childElementCount: 2
childNodes: NodeList(3) [div.sidebar-content, text, div.section-content.problem-content]
children: HTMLCollection(2) [div.sidebar-content, div.section-content.problem-content]
classList: DOMTokenList(2) ['section', 'problem', value: 'section problem']
className: "section problem"
clientHeight: 748
clientLeft: 0
clientTop: 0
clientWidth: 1290
contentEditable: "inherit"
dataset: DOMStringMap {vDcd49e84: ''}
dir: ""
draggable: false
elementTiming: ""
enterKeyHint: ""
firstChild: div.sidebar-content
firstElementChild: div.sidebar-content
hidden: false
id: "problem"
innerHTML: "..."
inputMode: ""
isConnected: true
isContentEditable: false
lang: ""
lastChild: div.section-content.problem-content
lastElementChild: div.section-content.problem-content
localName: "div"
namespaceURI: "http://www.w3.org/1999/xhtml"
nextElementSibling: div#contact.section.contact
nextSibling: text
nodeName: "DIV"
nodeType: 1
nodeValue: null
nonce: ""
offsetHeight: 748
offsetLeft: 0
offsetParent: div.v-application--wrap
offsetTop: 3340
offsetWidth: 1290
onabort: null
onanimationend: null
onanimationiteration: null
onanimationstart: null
onauxclick: null
onbeforecopy: null
onbeforecut: null
onbeforepaste: null
onbeforexrselect: null
onblur: null
oncancel: null
oncanplay: null
oncanplaythrough: null
onchange: null
onclick: null
onclose: null
oncontextmenu: null
oncopy: null
oncuechange: null
oncut: null
ondblclick: null
ondrag: null
ondragend: null
ondragenter: null
ondragleave: null
ondragover: null
ondragstart: null
ondrop: null
ondurationchange: null
onemptied: null
onended: null
onerror: null
onfocus: null
onformdata: null
onfullscreenchange: null
onfullscreenerror: null
ongotpointercapture: null
oninput: null
oninvalid: null
onkeydown: null
onkeypress: null
onkeyup: null
onload: null
onloadeddata: null
onloadedmetadata: null
onloadstart: null
onlostpointercapture: null
onmousedown: null
onmouseenter: null
onmouseleave: null
onmousemove: null
onmouseout: null
onmouseover: null
onmouseup: null
onmousewheel: null
onpaste: null
onpause: null
onplay: null
onplaying: null
onpointercancel: null
onpointerdown: null
onpointerenter: null
onpointerleave: null
onpointermove: null
onpointerout: null
onpointerover: null
onpointerrawupdate: null
onpointerup: null
onprogress: null
onratechange: null
onreset: null
onresize: null
onscroll: null
onsearch: null
onseeked: null
onseeking: null
onselect: null
onselectionchange: null
onselectstart: null
onstalled: null
onsubmit: null
onsuspend: null
ontimeupdate: null
ontoggle: null
ontouchcancel: null
ontouchend: null
ontouchmove: null
ontouchstart: null
ontransitioncancel: null
ontransitionend: null
ontransitionrun: null
ontransitionstart: null
onvolumechange: null
onwaiting: null
onwebkitanimationend: null
onwebkitanimationiteration: null
onwebkitanimationstart: null
onwebkitfullscreenchange: null
onwebkitfullscreenerror: null
onwebkittransitionend: null
onwheel: null
outerHTML: "..."
ownerDocument: document
parentElement: div#cridty
parentNode: div#cridty
part: DOMTokenList [value: '']
prefix: null
previousElementSibling: div#value.section.value
previousSibling: text
scrollHeight: 748
scrollLeft: 0
scrollTop: 0
scrollWidth: 1290
shadowRoot: null
slot: ""
spellcheck: true
style: CSSStyleDeclaration {accentColor: '', additiveSymbols: '', alignContent: '', alignItems: '', alignSelf: '', …}
tabIndex: -1
tagName: "DIV"
textContent: "..."
title: ""
translate: true
virtualKeyboardPolicy: ""
[[Prototype]]: HTMLDivElem
这是对象的控制台日志,该对象在菜单组件中的服务器上使用 scroll() 函数来定义滚动的位置以及链接何时处于活动状态以及何时不处于活动状态:
active: (…)
hash: (…)
id: (…)
posBottom: 3484
posTop: 2736
它只有一个部分不起作用,其他所有部分都很好。
选项 2:
我尝试使其工作的第二种方法是使用锚链接,当单击菜单中的链接时,我让它滚动到右侧部分,但现在的问题是我需要更改哈希是用户滚动到时的 url一节。我试图用this.$router.push({path: element.hash})
. 当用户进入该部分时,url 会发生变化,但问题是每次 $router.push 运行时,滚动体验都会变得非常糟糕,因为它会在用户向下滚动到新部分时尝试回滚到该部分。
现在我在这两者之间跳来跳去,不知道哪一个更适合投资我的时间。