How to bind an event listener only once with Unpoly

Updated . Posted . Visible to the public.

You can use Unpoly's up.on Show archive.org snapshot with a named listener function and immediately unbind this event listener with { once: true }:

up.on('up:fragment:inserted', { once: true }, function () { ... })

In Unpoly 1 you can immediately unregister the listener with up.off Show archive.org snapshot :

up.on('up:fragment:inserted', function fragmentInsertedCallback() {
  up.off('up:fragment:inserted', fragmentInsertedCallback)
  // ... code for the callback function, which should run only once
})

Example case

I had an Unpoly compiler for a tab navigation, which sets an -active class per default to the first tab link and removes it from all other tab links. If another tab link is clicked, the -active class switches to the clicked link.
In a Jasmine spec I wanted to test this behaviour.
Unpoly's up.hello Show archive.org snapshot emits an up:fragment:inserted event, in whose callback function I can check the default classes.
I needed to deactivate the listener to this event after it was triggered once, because it will also be triggered if I click on another tab link.

up.on('up:fragment:inserted', function fragmentInsertedCallback() {
  up.off('up:fragment:inserted', fragmentInsertedCallback)
  // check if tabLink1 is active, when the compiler starts
  expect(tabLink1.classList.contains('-active')).toEqual(true)
  expect(tabLink2.classList.contains('-active')).toEqual(false)
})

up.hello(tabNavigation) // triggers the tab navigation compiler

tabLink2.click()

expect(tabLink1.classList.contains('-active')).toEqual(false)
expect(tabLink2.classList.contains('-active')).toEqual(true)
Last edit
Michael Leimstädtner
License
Source code in this card is licensed under the MIT License.
Posted to makandra dev (2022-03-16 10:25)