Posts Tagged ‘Javascript’

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. šŸ˜‰

No Comments

Setting several properties of dataset of any DOM element, writing to the dataset property

Tuesday, June 21st, 2022

One of the greatest additions in writing JS of the last years for writing clean code are arrow functions, classes and several ways of Destructuring assingment.

Arrow functions let you skip, several verbose terms like the function keyword, return keyword and {} character, while maintaining readability. Easy, once you mastered the new syntax!.

What is Destructuring assingment?

Let’s assume you fetch a stock json:

let json= {name:"SHELL PLC",isin:"GB00BP6MXD84",price:"25.00","volume":"2500000",time:"2022-06-22:09-06"}

They old way of dealing with this was to write everything out to assign values to variables:

var name = json.name;
var isin= json.isin
var price = json.price;
var volume=json.volume;
var time = json.time;

Destructuring assingment let you do this more succinct:

let {name,isin,price,volume,time}=json

That is nice code.

Destructuring arrays, or csv rows:

let {name,isin,price,volume,time}=row.split(",")

Sure there is more on parsing cvs rows than just splitting on “,” but this is an example and you get the drift. When you totally control the csv file, using “,” only as separator, it should do the job.

Writing to the datatset property?

I dearly miss something for setting the dataset property of an element concisely.

The dataset read-only property of the HTMLElement interface provides read/write access to custom data attributes (data-*) on elements.

Note: The dataset property itself can be read, but not directly written. Instead, all writes must be to the individual properties within the dataset, which in turn represent the data attributes.

So you can’t simply do something like this:

document.querySelector("#stock").dataset=json

You have to write it all out, and that isĀ  verbose:


let elStock = document.querySelector("#stock")
elStock.dataset.name=json.name;
elStock.isin=json.isin
elStock.price=json.price

Well there is a workaround.

Imitate writing to the dataset property directly, Object.assign()

According to the specs you can’t directly write the dataset, but you can do this:

Object.assign(document.querySelector("#stock"),json)

Result:

<body data-name="SHELL PLC" data-isin="GB00BP6MXD84" data-price="25.00" data-volume="2500000" data-time="2022-06-22:09-06">

A piece of cake. That is as easy as writing the dataset.property directly.

To extract dataset into variables destructuring assignment does work.

let {name,isin,price}=document.body.dataset

I used `Object.assign` in an older project for writing several properties to the style attribute, but it works as well for the dataset property.

No Comments

Browser performance and CPU load

Tuesday, June 14th, 2011

Chromium is using 2 cores and Opera isn’t running full speed on Sunspider JS benchmark. That is the outcome of a simple test running TOP while taking the sunspider benchmark on a quadcore (AMD 630) Ubuntu 64 machine with the three main browsers: Chromium, Firefox and Opera. Opera 11.11 is surprisingly never using more then 80% CPU while Firefox 4 is using 100% and Chromium 12 150%. A quadcore can take 400%, when all 4 CPU cycles are fully utilized. Opera is the slowest performer on the benchmark, no surprise and Firefox is somehow disabling graphical output: nearly no load on X-server, and no visual graphical output, while Opera and in a lesser extent Chromium show a lot of flickering and flashing. Opera is also putting a bigger load on Compiz, the compositing window manager for Linux, AKA 3d eye candy. But Opera, as said before, is also giving more visual feedback about downloading files and stuff with an animated icon in the addressbar.

Sunspider benchmark results

Firefox 4:	Total:		   355.6ms +/- 2.6%
Chromium 12:  Total:		   348.2ms +/- 4.9%
Opera 11.11:  Total:		   413.2ms +/- 3.3%

TOP results

Firefox 4
Tasks: 277 total,   2 running, 273 sleeping,   1 stopped,   1 zombie
Cpu(s): 27.1%us,  3.5%sy,  0.0%ni, 69.0%id,  0.3%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   5093632k total,  5016508k used,	77124k free,   220824k buffers
Swap:  9055228k total,		0k used,  9055228k free,  2074600k cached

PID USER	  PR  NI  VIRT  RES  SHR S %CPU %MEM	TIME+  COMMAND
7063 user	   20   0  923m 325m  41m R  101  6.5   2:46.61 firefox-bin
2193 root	   20   0  235m 131m  32m S   12  2.6  12:11.16 Xorg
3119 user	   20   0  374m  62m  20m S	8  1.3   5:13.44 compiz

Chromium 12
Tasks: 280 total,   3 running, 273 sleeping,   3 stopped,   1 zombie
Cpu(s): 44.0%us,  9.0%sy,  0.0%ni, 46.3%id,  0.8%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   5093632k total,  4856072k used,   237560k free,   217760k buffers
Swap:  9055228k total,		0k used,  9055228k free,  2011968k cached

PID USER	  PR  NI  VIRT  RES  SHR S %CPU %MEM	TIME+  COMMAND
7317 user	   20   0  880m  81m  26m R  102  1.6   1:20.46 chromium-browse
2193 root	   20   0  243m 138m  40m S   44  2.8  13:07.53 Xorg
7295 user	   20   0  519m  51m  31m R   41  1.0   0:37.04 chromium-browse
3119 user	   20   0  374m  62m  20m S   11  1.3   5:33.46 compiz

Opera 11.11
Tasks: 280 total,   4 running, 272 sleeping,   3 stopped,   1 zombie
Cpu(s): 23.3%us, 11.3%sy,  0.0%ni, 64.1%id,  1.2%wa,  0.0%hi,  0.2%si,  0.0%st
Mem:   5093632k total,  4849588k used,   244044k free,   217972k buffers
Swap:  9055228k total,		0k used,  9055228k free,  2004908k cached

PID USER	  PR  NI  VIRT  RES  SHR S %CPU %MEM	TIME+  COMMAND
6051 user	   20   0  863m 428m  29m S   81  8.6  13:51.12 opera
2193 root	   20   0  236m 131m  32m R   47  2.6  13:22.27 Xorg
3119 user	   20   0  374m  62m  20m R   18  1.3   5:38.20 compiz

Conclusion

Seems that Opera isn’t going full throttle on benchmarks. I wonder why that is. Chromium is the only browser that is using multiple cores, but it isn’t actually much faster than Firefox. Another interesting thing is that Chromium feels the snappier browser but actually is stressing your PC more.

1 Comment

Canvas Rendering: Skewing Images by Javascript

Saturday, November 8th, 2008

The new HTML5 CANVAS element gives the developer pixel-poking magic. Poke and peek are functions from the good old days that offered the only geeky way to set and read-out individual bytes in the (graphic) memory.

Sure things are better nowadays. To understand how canvas works, imagine an IMG element, of which every pixel can be set individually or loaded from a IMG source.

Opera screenshot canvas element

Opera screenshot canvas element

This means you can filter images, copy them, translate, rotate, scale, in short: a lot. It can also add drop-shadow, although at the moment this is only fully supported by Safari and partially by Opera. Probably Firefox will add support in the upcoming 3.1.

sec



Rendering is best in Opera and Firefox. Safari and Chrome look awful. Webkits’ canvas seems designed to work only with integers while Opera and Firefox translates floats into some anti-alias rendering. Better but probably slower. Opera’s rendering is quite slow.

Update 25-02-2011

Rendering time screen:

Chrome 9 : 50 msec
Opera 11.01:Ā  667 msec
Firefox 3.613: 2829 msec

Opera and Firefox look fine, Chrome’s rendering is jagged.