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

dom-handler

v0.2.1

Published

W3C DOM handleEvent utility

Downloads

7

Readme

dom-handler

Live Test Page

A simple fully cross browser library that could change forever the way you interact with DOM and events.

It's completely dependencies free, it's natively fast, and it fits in less than 1KB.

example

The most basic example is a click, performed once, and never again.

Handler.add('body', {
  click: function (e) {
    console.log(e.type);
    this.releaseEvent(e);
  }
});

The handler object is not even assigned once, it's capable of handling any kind of event and remove whenever it's needed via this.releaseEvent(event) and it's natively bound without any need to use function bind, which also means less amount of RAM needed, always able to drop a handler/listener without the need to reference each bound function, and ideally better performance too.

To remove from any handler, at any time, all attached events:

Handler.add(document.documentElement, {
  click: function (e) {
    console.log(e.type);
  },
  dropHandler: function (e) {
    Handler.remove(e.currentTarget, this);
  }
});

By W3C specifications the event.currentTarget property is always present and is always the original Node where the generic function hr handler were attached. Accordingly, a simple call like this:

document.documentElement.dispatchEvent(
  new CustomEvent('dropHandler')
);

Will free forever from all listeners defined in the handler object.

capture

This simple script lets us capture events, if necessary, through a basic key convention:

Handler.add(document.documentElement, {
  clickCapture: true,
  click: function (e) {
    console.log(e.type);
  }
});

In this case the event phase will be capturing instead of bubbling.

delegate

It is possible to delegate listeners too, handy to simplify and boost up listeners per nodes.

Handler.add(
  'ul.menu',
  {
    // each li inside this ul will trigger `click`
    clickDelegate: 'li',
    click: function (e) {
      console.log(e.delegated.nodeName); // LI
    }
  }
);

custom methods and properties

only properties that are functions, starts with [a-zA-Z], and are not handleEvent or releaseEvent will be set as DOM handler, feel free to use any other name or value to do whatever you want.

Handler.add(document.documentElement, {
  counter: 0,
  _showWinner: function () {
    alert('Congratulations, you did ' + this.counter + '!');
  },
  click: function (e) {
    if (++this.counter === 10) {
      this.releaseEvent(e);
      this._showWinner();
    }
  }
});

performance

The worst case scenario I could measure triggers 3600 operations per second in a cheap Android 2 hardware.

While I believe if we have 3000 listeners acting on touchmove, the problem is not exactly the handler, talking with numbers this means that even mousemove or thouchmove events, fired at 60FPS, will never be concretely affected since the amount of time taken natively to dispatch these kind of events is, again in the worst case scenario, 0.27 millisecons out of 16.66 milliseconds we have per each frame.

On average, mobile phones will simply have 0.2 millisecond less time to do everything needed to be done and whenever this will be the real world bottleneck, you can always change that single listener to use a callback instead of rewriting the whole app.

no more leaks

The feature that comes for free is the ability to somehow link an object to a DOM node without needing to reference it. Once the DOM node will be removed and its reference canceled, there won't be any leak left since the counter reference for all handlers will be just 0. This is a very welcome implicit side effect, and an easier way than WeakMaps. It also means we can create any sort of pattern and behavior simply via events, customs or user-generated, interacting with a transparent, by default unreachable, and for this reason more secure, JavaScript object, able to do much more than a generic node.dataset access.

As Summary

This is the easiest, yet performant and probably the most efficient way to deal with one or more handlers, confining as plugin objects different behaviors or logic without interferring with each other.

What About IE8 ?

If you use upfront a DOM4 normalizer like this one you can forget about IE8 problems as well as function expressions VS function declarations since adding and removing an object won't ever suffer those kind of problems!