Archive for the ‘HTML5’ Category

No Comments

Adding events to elements the simple way, using optional chaining

Thursday, August 11th, 2022

On modern JavaScript driven or enhanced sites the HTML DOM is sprinkled with events.

Since the birth of HTML5, (and decline of the worst (most expensive) browser ever: Microsoft Explorer) the appropriate way of attaching events is using AddEventListener()

document.querySelector('selector').addEventListener('click', function () { console.log("Hi, you clicked") });

This works only if the queried element does exists. Otherwise you”ll get an error and further execution of the script will fail.

So you’ll need to add a conditional check, the querySelector function returns null when the element can’t be found:

if (document.querySelector('selector'))
 document.querySelector('selector').addEventListener('click', function () {
console.log("Hi, you clicked")
});

Modern JavaScript is developing

But functionality to JavaScript is added every year and now there is a optional chaining and that feature is exactly what we need.

Optional chaining was introduced in ES2020. It’s supported by all modern updated browsers.

Optional chaining

Simply add a ? to a object property or method to check if it is existing.

book.author?.name

This will not cause an error if book.author is nullish (not existing)

Using this syntax and arrow functions the new code for attaching an event to an element is:

document.querySelector('selector')?.addEventListener('click', ()=>console.log("Hi, you clicked"));

If the element doesn’t exist, it will not do anything (document.querySelector('selector') is nullish). It won’t cause an error.

Exactly what we need!

UPDATE

What I miss though is something like this:

document.querySelector("#menu-comments a")?.href += "?comment_status=moderated";

Above oneliner is my simple solution to set the default Comments-link in WordPress to show the pending or new comments by default. Most (99%) are SPAM unfortunately, so this way it’s safer to select all and do a bulk action delete permanently or mark as spam.

But above onliner gives an JS error:

Uncaught SyntaxError: invalid assignment left-hand side

To my surprise there was a proposal in the spec to allow this. I would welcome that change, hopefully it will come one day.

I hate writing this verbose conditional:

if (document.querySelector("#menu-comments a"))
document.querySelector("#menu-comments a").href += "?comment_status=moderated";

Maybe I should start writing CoffeeScript or use Babel by default. 😉

13 Comments

Fixing the iPhone CSS hover problem on iOS

Wednesday, November 6th, 2019

Mobile phones don’t have a mouse, your greasy fat touchy fingers have to do the job, they kinda act like a giant mouse.

There is major difference: a mouse can click, drag and  hover above the screen, while your fingers can click and swipe, but not hover. Well they can, but nothing is happening then. 🙂

The official terms here are: mouse-events, touch events, and pointer events, for both mouse and touch events. So touch events don’t know about hover, cause that is a mouse event.

So those nice old style CSS-only dropdown menu’s won’t work on your phone, because the depend on :hover.

Hover events work on mobile Android or Firefox browsers, as those browser vendors looked for compatibility, and made a click with your fingers act like hover on elements that are not a link. That is smart thinking, and good care for compatibility. Keep old sites working. Keep sites accessible without forcing Javascript.

But they don’t work on iPhone or mobile Safari, so we need a solution for that.

Plain HTML is and has always been responsive. It’s the CSS that destroyed it, by setting explicit width.  Well there was no max-width, so designers had not much choice. But remove all CSS and magically your HTML will be responsive, except for tables and large images, but at least you can scroll them into sight so everything is still accessible.

Pity the Apple people. An iPhone with mobile Safari doesn’t do :hover, breaking compatibility for old sites, and forcing webdevelopers to use `Javascript`  for these trivial things. Annoying.

There are examples on the internet how to fix that, like adding an onclick attribute to every element you want the :hover rule for, but that’s adding a lot of code, and the elements the don’t hide again when you click somewhere else.

We need better solutions!

How to make :hover  work on Safari iOS on iPhones and iPads.

Here are a few very simple options, that I came up with having a new iPhone 11 around for a couple of days. Tested on the latest iOS 13.
(more…)

No Comments

Sorting with grid

Wednesday, April 12th, 2017

A while ago we showed you a way to use flexbox for sorting lists and tables. This month the powerful CSS Grid layout system went unprefixed in all major browsers.

In short Grid is for two dimension grids, while Flexbox is better suited for one dimensional layouts, like a nav bar. They can work together, a grid cell can be a flexbox container and vice versa.

The grid system is rather easy to grasp, it doesn’t have much surprises.

Let’s go over to the sorting trick:

Just push the buttons or table header to sort the stuff.

How does it work

Sort the elements on text and write the grid order attribute for CSS.

<li style="grid-row-start: 7;">scstqehfr</li>

The main `win` of css sorting is you don’t need to modify the DOM, which is expensive in most browsers. That said, you need some CSS trickery to get tables look like tables at the moment a tbody has a grid or flexbox display-layout.

Read more about the Basic concepts of grid layout here.

1 Comment

Breaking the bad, pushing a worse internet (part II)

Sunday, June 21st, 2015

In an earlier post we lamented the behavior of multinationals by dropping noble classic Internet principles like Graceful degradation and progressive enhancement to strengthen their business model at a high security and privacy cost for users.

Go to a site with JS disabled and you see Nada. Zilch. On Google, on Twitter, Facebook tells us it can do much without JS. Nonsense, that is their policy, it’s not your fault.

(more…)

No Comments

Sorting with Flexbox

Wednesday, August 13th, 2014

The Flexible Box Layout Module is a very powerful tool to style your webpages. It offers simple solutions for things like `the Holy Grail`

Here we do a dirty sorting trick:

Just push the buttons or table header to sort the stuff.

How does it work

Sort the elements on text and write the order attribute for CSS.

<li style="order: 7;">scstqehfr</li>

Then set the elements to display flex on the ol element:

.sorted{
display:flex;
flex-flow:column;
flex-direction:column;
}

Be aware:

Sorting this way is kind of superficial, it’s only ordered through CSS: It will show the elements in different order, but in the DOM there is no change at all. So traversing or accessing elements can be surprising, it will go in original/DOM order.

Sorting an table through Flexbox ruins the layout, because it resets the display property from `table-*` to `flex-*`. An additional trick to write the width explicitly is needed to maintain layout.

No Comments

Spinners and sliders with just native javascript

Thursday, April 5th, 2012

In an earlier post we waved goodbye to jQuery UI for animations. CSS transform and transitions are more powerful, easier to maintain, hardware accelerated, and last but not least less code.

And you could save bandwidth by not loading jQuery UI.

And now I have rewritten the former example to drop jQuery, and believe it or not, it’s even less inline Javascript code. Sure the former example wasn’t really clever programmed – now we use event delegations – but it’s quiet astonishing that using native JS requires less code then the former jQuery example. And of course one library less to load.

Why can we drop jQuery in a lot of cases?

Because CSS animations aren’t working in old browsers anyway, so it doesn’t matter that don’t understand the latest HTML5/ECMA Script 5 / Javascript additions. That’s what graceful degradation means. No eye-candy for older browsers.

Important HTML5/ECMA Script 5 / Javascript additions:

  • classList api: easy toggling, adding and removing of classes.
  • document.querySelectorAll, the native selector API,  get you’re DOM elements like the way you do with CSS
  • new powerful array functions, like forEach etc.
  • even Microsoft products (Explorer 9) now support Javascript specs: like addEventListener, XMLHttpRequest,  javascript objects instead of ActiveX objects etc.
  • innerHTML, outerHTML
  • DOM traversal

Above list is not complete, but in most cases jQuery was used for things like, binding events, toggling classes, selecting elements, add elements, and ajaxify sites.

Here is the new example

And the used Javascript code:


(function(){
var spinner = document.getElementById("spinner"),i=null
spinner.addEventListener('click', function(event){
// event.preventDefault()
// event.stopPropagation()
// which element is the target
i = Array.prototype.indexOf.call(spinner.children, event.target);
// if(window.console) console.log(i,event)
switch(i){
case 1:
// clicked left, pop -> unshift
spinner.insertBefore(spinner.lastElementChild, spinner.firstElementChild)
break;
case 3:
// clicked right shift -> push
spinner.appendChild(spinner.firstElementChild)
break;
default:
}
// Opera bug workaround
spinner.classList.toggle('operabug')
}, false);
})()

Caveats

The Opera bug with DOM mutations and CSS transform/transitions isn’t resolved yet unfortunately. Somehow the DOM mutations don’t seem to trigger a reflow.

UPDATE: there is an easy fix for the Opera Bug, trigger a reflow by setting a bogus class on any element:

// Opera bug workaround
spinner.classList.toggle('operabug')