use event delegation for better perf
This commit is contained in:
parent
08c19691a9
commit
e6304cbbf3
|
@ -1,6 +1,9 @@
|
|||
<article class="status-article {{getClasses(originalStatus, timelineType, isStatusInOwnThread)}}"
|
||||
tabindex="0" on:click="onClickOrKeydown(event)" on:keydown="onClickOrKeydown(event)"
|
||||
aria-posinset="{{index}}" aria-setsize="{{length}}"
|
||||
tabindex="0"
|
||||
delegate-click-key="{{delegateKey}}"
|
||||
delegate-keydown-key="{{delegateKey}}"
|
||||
aria-posinset="{{index}}"
|
||||
aria-setsize="{{length}}"
|
||||
aria-label="Status by {{originalStatus.account.display_name || originalStatus.account.username}}"
|
||||
on:recalculateHeight>
|
||||
{{#if (notification && (notification.type === 'reblog' || notification.type === 'favourite')) || status.reblog}}
|
||||
|
@ -87,8 +90,20 @@
|
|||
import { store } from '../../_store/store'
|
||||
import identity from 'lodash/identity'
|
||||
import { goto } from 'sapper/runtime.js'
|
||||
import { registerDelegate, unregisterDelegate } from '../../_utils/delegate'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
let delegateKey = this.get('delegateKey')
|
||||
let onClickOrKeydown = this.onClickOrKeydown.bind(this)
|
||||
registerDelegate('click', delegateKey, onClickOrKeydown)
|
||||
registerDelegate('keydown', delegateKey, onClickOrKeydown)
|
||||
},
|
||||
ondestroy() {
|
||||
let delegateKey = this.get('delegateKey')
|
||||
unregisterDelegate('click', delegateKey)
|
||||
unregisterDelegate('keydown', delegateKey)
|
||||
},
|
||||
components: {
|
||||
StatusSidebar,
|
||||
StatusHeader,
|
||||
|
@ -132,6 +147,7 @@
|
|||
computed: {
|
||||
originalStatus: (status) => status.reblog ? status.reblog : status,
|
||||
statusId: (originalStatus) => originalStatus.id,
|
||||
delegateKey: (statusId, timelineType, timelineValue) => `status-${timelineType}-${timelineValue}-${statusId}`,
|
||||
contextualStatusId: ($currentInstance, timelineType, timelineValue, status, notification) => {
|
||||
return `${$currentInstance}/${timelineType}/${timelineValue}/${notification ? notification.id : ''}/${status.id}`
|
||||
},
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
// Delegate certain events to the global document for perf purposes.
|
||||
|
||||
import { mark, stop } from './marks'
|
||||
|
||||
const callbacks = {}
|
||||
|
||||
if (process.browser && process.env.NODE_ENV !== 'production') {
|
||||
window.delegateCallbacks = callbacks
|
||||
}
|
||||
|
||||
function onEvent(e) {
|
||||
let { type, keyCode, target } = e
|
||||
if (!(type === 'click' || (type === 'keydown' && keyCode === 13))) {
|
||||
// we're not interested in any non-click or non-Enter events
|
||||
return
|
||||
}
|
||||
mark('delegate onEvent')
|
||||
let attr = `delegate-${type}-key`
|
||||
let key
|
||||
let element = target
|
||||
while (element) {
|
||||
if ((key = element.getAttribute(attr))) {
|
||||
break
|
||||
}
|
||||
element = element.parentElement
|
||||
}
|
||||
if (key && callbacks[type] && callbacks[type][key]) {
|
||||
callbacks[type][key](e)
|
||||
}
|
||||
stop('delegate onEvent')
|
||||
}
|
||||
|
||||
export function registerDelegate(type, key, callback) {
|
||||
mark('delegate registerDelegate')
|
||||
callbacks[type] = callbacks[type] || {}
|
||||
callbacks[type][key] = callback
|
||||
stop('delegate registerDelegate')
|
||||
}
|
||||
|
||||
export function unregisterDelegate(type, key) {
|
||||
mark('delegate unregisterDelegate')
|
||||
callbacks[type] = callbacks[type] || {}
|
||||
delete callbacks[type][key]
|
||||
stop('delegate unregisterDelegate')
|
||||
}
|
||||
|
||||
if (process.browser) {
|
||||
document.addEventListener('click', onEvent)
|
||||
document.addEventListener('keydown', onEvent)
|
||||
}
|
Loading…
Reference in New Issue