npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

when-elements

v0.2.1

Published

Callbacks for when elements are added or removed from the DOM

Downloads

10

Readme

WhenElements

Callbacks for when elements are added or removed from the DOM.

  • No polyfills needed.
  • Works down to IE11 (cerca 2013).
  • Lightweight (~0.8kb min, ~0.5kb min+gzip).
  • Register start up and shut down callbacks for elements, based on CSS selectors.
  • Define multiple behaviors (different callbacks) for the same element.
  • Browser dependencies: MutationObserver, Set.

Install and import

Use WhenElements however you'd like.

  1. Global WhenElements, via CDN.
<script src="https://unpkg.com/when-elements"></script>
const { whenAdded, whenRemoved } = WhenElements
  1. ESM, via CDN.
import { whenAdded, whenRemoved } from 'https://unpkg.com/when-elements?module'
  1. ESM bundler.
npm install when-elements
import { whenAdded, whenRemoved } from 'when-elements'
  1. CJS module.
npm install when-elements
const { whenAdded, whenRemoved } = require('when-elements')

Examples

Create custom web components

Countdown until 0. Stop if the element is removed.

<my-countdown seconds="60"></my-countdown>
whenAdded('my-countdown', function (element) {
  const seconds = parseInt(element.getAttribute('seconds'))
  let count = seconds
  update()
  const intervalId = setInterval(() => {
    count--
    update()
  }, 1000)
  setTimeout(cleanup, 1000 * seconds)
  function update () {
    element.textContent = count
  }
  function cleanup () {
    clearInterval(intervalId)
  }
  return cleanup
})

Extend element

Remove button after it is clicked a maximum number of times.

<button is="clicker" data-maxclicks="3">Remove</button>
whenAdded('[is="clicker"]', function (element) {
  let clicks = parseInt(element.dataset.maxclicks)
  update()
  element.addEventListener('click', function () {
    clicks--
    if (clicks > 0) {
      update()
    } else {
      element.remove()
    }
  })
  function update () {
    element.textContent = `Remove (${clicks} more click${clicks === 1 ? '' : 's'})`
  }
})

More

Review more examples in ./test.

API

whenAdded

Call a function when any new or existing DOM elements match the CSS selector. It will be called only once per element. Any number of whenAdded() declarations could include the same selector or involve the same element.

whenAdded(selector: String, callback: Function)
whenAdded(selector, (element) => {
  // Initialize.

  // Optional: Return a function to be called when
  // the element no longer matches the selector or
  // is removed from the DOM. This is the same as:
  // `whenRemoved(selector, element, () => { ... })`
  return () => {
    // Clean up.
  }
})

added() is an alias to whenAdded(), primarily to make it easier to read if the global is not deconstructed.

WhenElements.added()

whenRemoved

Call a function when the element is removed from the DOM or no longer matches the CSS selector. It will be called only once per element.

whenRemoved(selector: String, element: HTMLElement, callback: Function)
whenRemoved(selector, element, () => {
  // Clean up.
})

removed() is an alias to whenRemoved(), primarily to make it easier to read if the global is not deconstructed.

WhenElements.removed()

Inspiration

This library is inspired by wickedElements, which is an enhancement of regularElements, which is inspired by window.customElements. Notable differences:

  1. regularElements tries to adhere closely to the customElements spec, so it looks familiar. WhenElements provides a simple API, without trying to adhere to the customElements spec.
  2. onconnected() can be called multiple times per element with regularElements. wickedElements adds init() to regularElements, to guarantee a single initialization per element. whenAdded() behaves this way by default.
  3. ondisconnected() is called when the element is removed from the DOM, but not when the element no longer matches the selector provided in define(). This could be limiting, depending on the use case. whenRemoved() solves this.
  4. regularElements protects against multiple definitions using the same selector. whenAdded() does not check this. That way, multiple behaviors could be defined in different places, even if they affect the same set of elements.

Backlog

whenAdded():

  1. Return a function to cancel whenAdded().
  2. An optional options argument could allow for changes in the default behavior.
  3. Option: Cancel after first match.
  4. Option: Cancel after N matches.
  5. Demonstrate how to bundle multiple whenRemoved() calls in the single return function.
  6. Add tests.

whenRemoved():

  1. Return a function to cancel whenRemoved().
  2. Make selector optional and target required.
  3. Make target optional and selector required.
  4. Add tests.

Other potential methods:

  1. register(): Define other methods to hook into the same DOM mutation callback that whenAdded() and whenRemoved() uses. Confirm if there's any performance penalty to having multiple duplicate MutationObserver declarations.
  2. get(): Get an array of initialized elements.