-
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathVueSkipToSingle.vue
75 lines (66 loc) · 1.3 KB
/
VueSkipToSingle.vue
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
<template>
<component
:is="comp"
v-bind="props"
@click.prevent="handleFocusElement"
class="vue-skip-to__link"
>
<slot>{{ label }}</slot>
</component>
</template>
<script>
export default {
name: 'VueSkipToSingle',
props: {
label: {
type: String,
default: 'Skip to main content'
},
to: {
type: String,
default: '#main'
}
},
computed: {
targetIsId () {
return this.to.substring(0, 1) === '#'
},
comp () {
if (this.targetIsId) return 'a'
return 'button'
},
props () {
if (this.targetIsId) {
return {
href: this.to
}
}
return {}
}
},
methods: {
handleFocusElement () {
if (this.targetIsId) {
const id = this.to.substring(1)
if (!id) return
const element = window.document.getElementById(id)
this.focusElement(element)
} else {
const element = window.document.querySelector(this.to)
this.focusElement(element)
}
},
focusElement (element) {
if (!element) return
if (
!/^(a|select|input|button|textarea)/i.test(
element.tagName.toLowerCase()
)
) {
element.setAttribute('tabindex', -1)
}
element.focus()
}
}
}
</script>