MoOx / pjax

Easily enable fast Ajax navigation on any website (using pushState + xhr)
MIT License
1.43k stars 124 forks source link

I want you to optimize your coding experience #247

Closed EmptyDreams closed 2 years ago

EmptyDreams commented 2 years ago

Now, if I need to write code that executes after the page loads, and it needs to execute on every page, I need to write:

const task = () => {......}
document.addEventListener(‘DOMContentLoaded’, task)
document.addEventListener('pjax:success', task)

The reason for registering both events is that the DOMContentLoaded event will not be executed if the JS is not loaded the first time the page is opened, and pjax:success will not be executed if the JS is loaded the first time the page is opened.

To make matters worse, if the code is embedded in an HTML document (that is, the code only needs to be executed on this page), I need to write:

const task = () => {......}
document.addEventListener(‘DOMContentLoaded’, task)
document.addEventListener('pjax:success', task)
document.addEventListener('pjax:send', function fun() {
    document.removeEventListener('pjax:success', task)
    document.removeEventListener('pjax:send', fun)
})

Because if I don't manually delete the event, the pjax:success event registered on this page will still be executed after I jump to another page, so I have to manually delete the pjax:success event registered on this page. (DOMContentLoaded doesn't matter because it only executes once.)

So I want to be able to add an event that is executed after the current page's DOM has been loaded, no matter how many times it has been loaded.

EmptyDreams commented 2 years ago

The second code can be changed to look like this:

const task = () => { ...... }
document.addEventListener('DOMContentLoaded', task)
document..addEventListener('pjax:success', function fun() {
    document.removeEventListener('pjax:success', fun)
    task()
})

So far I have solved this problem by manual encapsulation, I wrote the following in a JS that will be loaded by all pages:

document.addEventListener('DOMContentLoaded', () => {
    const pushEvent = () => document.dispatchEvent(new Event('kms:loaded'))
    pushEvent()
    document.addEventListener('pjax:success', pushEvent)
})

Then use it elsewhere:

document.addEventListener('kms:loaded', function fun() {
    document.removeEventListener('kms:loaded', fun)
    // do something...
})