Register only one `DOMContentLoaded` event listener in `onDOMContentLoaded` (#34158)

* refactor: reuse one DOMContentLoaded event listener in onDOMContentLoaded function

Instead of adding an event listener everytime the utility function is called, cache the callbacks and execute them all at once.

* refactor: drop iife for onDOMContentLoaded

Co-authored-by: XhmikosR <xhmikosr@gmail.com>
This commit is contained in:
alpadev 2021-06-22 19:19:55 +02:00 committed by GitHub
parent 56b000474c
commit 4927388197
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 3 deletions

View File

@ -201,9 +201,18 @@ const getjQuery = () => {
return null return null
} }
const DOMContentLoadedCallbacks = []
const onDOMContentLoaded = callback => { const onDOMContentLoaded = callback => {
if (document.readyState === 'loading') { if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback) // add listener on the first call when the document is in loading state
if (!DOMContentLoadedCallbacks.length) {
document.addEventListener('DOMContentLoaded', () => {
DOMContentLoadedCallbacks.forEach(callback => callback())
})
}
DOMContentLoadedCallbacks.push(callback)
} else { } else {
callback() callback()
} }

View File

@ -582,15 +582,24 @@ describe('Util', () => {
}) })
describe('onDOMContentLoaded', () => { describe('onDOMContentLoaded', () => {
it('should execute callback when DOMContentLoaded is fired', () => { it('should execute callbacks when DOMContentLoaded is fired and should not add more than one listener', () => {
const spy = jasmine.createSpy() const spy = jasmine.createSpy()
const spy2 = jasmine.createSpy()
spyOn(document, 'addEventListener').and.callThrough()
spyOnProperty(document, 'readyState').and.returnValue('loading') spyOnProperty(document, 'readyState').and.returnValue('loading')
Util.onDOMContentLoaded(spy) Util.onDOMContentLoaded(spy)
window.document.dispatchEvent(new Event('DOMContentLoaded', { Util.onDOMContentLoaded(spy2)
document.dispatchEvent(new Event('DOMContentLoaded', {
bubbles: true, bubbles: true,
cancelable: true cancelable: true
})) }))
expect(spy).toHaveBeenCalled() expect(spy).toHaveBeenCalled()
expect(spy2).toHaveBeenCalled()
expect(document.addEventListener).toHaveBeenCalledTimes(1)
}) })
it('should execute callback if readyState is not "loading"', () => { it('should execute callback if readyState is not "loading"', () => {