JavaScript - Events

Allow Ctrl- and Shift-clicking links in event handlers

I just recently updated a bunch of my click handlers to not act when the Ctrl or Shift keys are pressed during the click, so that links can be opened in new tabs or windows by the user if so wanted:

Code language: JavaScript

// Don't do anything and defer to the default action if a modifier key
// was pressed during the click (to open the link in a new tab, window,
// etc.) - note that this is a truthy check rather than a strict check
// for the existence of and boolean true value of the various event
// properties:
// * https://ambientimpact.com/web/snippets/conditional-statements-and-truthy-values-robust-client-side-javascript
// * https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/ctrlKey
// * https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/shiftKey
if (event.ctrlKey || event.shiftKey) {
  return;
}

An event for CSS position: sticky

Here’s a secret: You may not need scroll events in your next app. Using an IntersectionObserver, I show how you can fire a custom event when position:sticky elements become fixed or when they stop sticking. All without the use of scroll listeners.

[…]

One of the practical limitations of using CSS sticky position is that it doesn’t provide a platform signal to know when the property is active. In other words, there’s no event to know when an element becomes sticky or when it stops being sticky.

Async events in ServiceWorkers with "event.waitUntil"

It’s asynchronous, see? So even though all that network code appears before the return statement, it’s pretty much guaranteed to complete after the cache response has been returned. You can verify this by putting in some console.log statements:

Code language: JavaScript

caches.match(request)
.then( responseFromCache => {
  if (responseFromCache) {
      event.waitUntil(
          fetch(request)
          .then( responseFromFetch => {
              console.log('Got a response from the network.');
              caches.open(staticCacheName)
              .then( cache => {
                  cache.put(request, responseFromFetch);
              });
          })
      );
      console.log('Got a response from the cache.');
      return responseFromCache;
  }

Those log statements will appear in this order:

Got a response from the cache.
Got a response from the network.

That’s the opposite order in which they appear in the code. Everything inside the event.waitUntil part is asynchronous.

Here’s the catch: this kind of asynchronous waitUntil hasn’t landed in all the browsers yet. The code I’ve written will fail.

But never fear! Jake has written a polyfill. All I need to do is include that at the start of my serviceworker.js file and I’m good to go:

Code language: JavaScript

// Import Jake's polyfill for async waitUntil
importScripts('/js/async-waituntil.js');