0%

JS 锚点偏移

锚点点击后,可以滚动到指定的Dom元素,这个dom元素会贴近最顶部

但是顶部有个浮动的Header,所以需要在滚动的时候进行偏移。

锚点偏移

网上的方法很多,暗锚、添加顶部占位,后来我发现了个牛逼方法,真的牛逼

offsetting an html anchor to adjust for fixed header

改了一下,如下

简单实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
function test() {

const { document } = window
const { history } = window
const { location } = window
const HISTORY_SUPPORT = !!(history && history.pushState)

const anchorScrolls = {
ANCHOR_REGEX: /^#[^ ]+$/,
OFFSET_HEIGHT_PX: 64,

/**
* Establish events, and fix initial scroll position if a hash is provided.
*/
init: function() {
this.scrollToCurrent()
window.addEventListener('hashchange', this.scrollToCurrent.bind(this))
document.body.addEventListener('click', this.delegateAnchors.bind(this))
},

/**
* Return the offset amount to deduct from the normal scroll position.
* Modify as appropriate to allow for dynamic calculations
*/
getFixedOffset: function() {
return this.OFFSET_HEIGHT_PX
},

/**
* If the provided href is an anchor which resolves to an element on the
* page, scroll to it.
* @param {String} href
* @return {Boolean} - Was the href an anchor.
*/
scrollIfAnchor: function(href, pushToHistory) {
let match = '',
rect,
anchorOffset

if (!this.ANCHOR_REGEX.test(href)) {
return false
}

match = document.getElementById(href.slice(1))

if (match) {
rect = match.getBoundingClientRect()
anchorOffset = window.pageYOffset + rect.top - this.getFixedOffset()
window.scrollTo(window.pageXOffset, anchorOffset)

// Add the state to history as-per normal anchor links
if (HISTORY_SUPPORT && pushToHistory) {
history.pushState({}, document.title, location.pathname + href)
}
}

return !!match
},

/**
* Attempt to scroll to the current location's hash.
*/
scrollToCurrent: function() {
console.log('滚动条')
this.scrollIfAnchor(window.location.hash)
},

/**
* If the click event's target was an anchor, fix the scroll position.
*/
delegateAnchors: function(e) {
const elem = e.target

if (
elem.nodeName === 'A' &&
this.scrollIfAnchor(elem.getAttribute('href'), true)
) {
e.preventDefault()
}
}
}

anchorScrolls.init()
}

test()

转载来源

修改之前的代码转载自 - https://stackoverflow.com/a/13067009