JavaScript

Introduction to HTML5 form validation

I recently embarked on improving the client-side form validation for a client. There were about 400 lines of form validation code stuffed inside a 1000 line form_helper.js. I looked for lightweight form validation scripts but after some hemming and hawing I decided to try my hand (again) at native HTML5 Form Validation.

If you’ve ever experimented with HTML5 Form Validation, you’ve probably been disappointed. The out-of-box experience isn’t quite what you want. Adding the required attribute to inputs works wonderfully. However the styling portion with input:invalid sorta sucks because empty inputs are trigger the :invalid state, even before the user has interacted with the page.

I finally sat down and spent a couple days trying to make HTML5 Form Validation work the way I want it. I had the following goals:

  1. Leverage browser-level feedback, free focus management and accessible labelling
  2. Only validate inputs on submit
  3. Styling with .error class

With this wishlist in hand, I set off and found a solution that works with only 6 lines of code.

Tags: 

How many people have JavaScript disabled or unavailable?

In 2013, the UK’s Government Digital Service did an experiment to determine how many of their users weren’t receiving JavaScript. You might assume, as I did years ago, that the only two options were either that users would have JavaScript enabled, or have disabled it explicitly via their browser’s settings or an addon. Unfortunately, those aren’t the only two options. The majority of users that don’t receive JavaScript likely don’t do so by choice.

They found that 1.1% of users didn’t execute their JavaScript test. Of those, only 0.2% either explicitly disabled JavaScript or used a browser that didn’t support it. The remainingly 0.9% did not indicate they didn’t support JavaScript, but were not executing the test.

‘noscript’ tags will only be followed by browsers that explicitly have JavaScript disabled or don’t support JavaScript at all. So a significant number of people had a JavaScript enabled browser but still didn’t run the scripts successfully.

It’s hard to know exactly why these browsers didn’t run the JavaScript, but a number of possible reasons are:

  • corporate or local blocking or stripping of JavaScript elements
  • existing JavaScript errors in the browser (ie from browser add-ons, toolbars etc)
  • page being left between requesting the base image and the script/noscript image
  • browsers that pre-load pages they incorrectly predict you will visit
  • network errors, especially on mobile devices
  • any undoubtedly many more I haven’t even thought about…

The takeaway? Do not assume that everyone has JavaScript, or will have it execute reliably even if they haven’t disabled it.

Tags: 

Go beyond console.log with the Firefox Debugger

Promo art for the Firefox Debugger Playground: a styled insect with the words "go beyond console.log" below it.

console.log is no debugger. It’s great for figuring out what your JavaScript app is up to, but it’s limited to spitting out a minimal amount of information. If your code is complex, you’ll need a proper debugger. That’s why we’ve added a new section to the Firefox Devtools Playground that’s all about debugging. We’ve built four basic lessons that use the Firefox Debugger to examine and repair a simple JavaScript to-do app.

Tags: 

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.

Tags: 

Intersection Observer

What do infinite scrolling, lazy loading, and online advertisements all have in common?

They need to know about—and react to—the visibility of elements on a page!

Unfortunately, knowing whether or not an element is visible has traditionally been difficult on the Web. Most solutions listen for scroll and resize events, then use DOM APIs like getBoundingClientRect() to manually calculate where elements are relative to the viewport. This usually works, but it’s inefficient and doesn’t take into account other ways in which an element’s visibility can change, such as a large image finally loading higher up on the page, which pushes everything else downward.

Things get worse for advertisements, since real money is involved. As Malte Ubl explained in his presentation at JSConf Iceland, advertisers don’t want to pay for ads that never get displayed. To make sure they know when ads are visible, they cover them in dozens of tiny, single-pixel Flash movies whose visibility can be inferred from their framerate. On platforms without Flash, like smartphones, advertisers set up timers to force browsers to recalculate the position of each ad every few milliseconds.

These techniques kill performance, drain batteries, and would be completely unnecessary if the browser could just notify us whenever an element’s visibility changed.

That’s what IntersectionObserver does.

Tags: 

Flash is in the pan

Now browsers have audio. They have video. They even have WebGL and VR. And all those technologies work on mobile. The writing’s been on the wall for Flash for a while. Yet still, I’m sad to see it go. It was a brilliant crucible of creativity. A forge for many emerging artists in the field of creative coding, and many of the concepts from Flash and ActionScript were the proving grounds for their modern browser equivalents.

I’ll be looking back fondly on those years, rather than spitting on Flash’s grave. And as we see the last of the great browser plugins disappear* I hope you’ll join me in celebrating the creative culture that it nurtured.

*RealPlayer 4eva!

Tags: 

Introducing sphinx-js, a better way to document large JavaScript projects

Until now, there has been no good tool for documenting large JavaScript projects. JSDoc, long the sole contender, has some nice properties:

  • A well-defined set of tags for describing common structures
  • Tooling like the Closure Compiler which hooks into those tags

But the output is always a mere alphabetical list of everything in your project. JSDoc scrambles up and flattens out your functions, leaving new users to infer their relationships and mentally sort them into comprehensible groups. While you can get away with this for tiny libraries, it fails badly for large ones like Fathom, which has complex new concepts to explain. What I wanted for Fathom’s manual was the ability to organize it logically, intersperse explanatory prose with extracted docs, and add entire sections which are nothing but conceptual overview and yet link into the rest of the work.

The Python world has long favored Sphinx, a mature documentation tool with support for many languages and output formats, along with top-notch indexing, glossary generation, search, and cross-referencing. People have written entire books in it. Via plugins, it supports everything from Graphviz diagrams to YouTube videos. However, its JavaScript support has always lacked the ability to extract docs from code.

Now sphinx-js adds that ability, giving JavaScript developers the best of both worlds.

Tags: 

{{ mustache }} - Logic-less templates

Mustache can be used for HTML, config files, source code - anything. It works by expanding tags in a template using values provided in a hash or object.

We call it “logic-less” because there are no if statements, else clauses, or for loops. Instead there are only tags. Some tags are replaced with a value, some nothing, and others a series of values.

Tags: 

Pages