Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Saturday, May 10, 2025

Javascript: Unexprected Symbol.iterator

Lets validate some data, and lets do some smart checks with a unknown random schema. Lets same why wnat to check internal id references, and of course internal ids wil be in iternal things, lets assume arrays for now:

for (collection of Object.values(data)) {
  for (i of collection) {
    for (field of Object.values(i)) {
      for (item of field) {
        // check item.id
      }
    }
  }
}

But someone decided to wrap arrays into classes because, lets be honest, pure json inside js never stays pure. So lets check the iterator symbol magic:

for (field of Object.values(i)) {
  if (!field[Symbol.iterator]) continue;
  for (item of field) {
    // check item.id
  }
}

Perferct, but wait... why the item takes values of single letter strings. Oh wait, dont tell me that this is a thing:

"test"[Symbol.iterator]

Yes it is, so lets add it to the condition:

typeof field === "string" || !field[Symbol.iterator]



done_

Wednesday, April 16, 2025

Techniques: Dev inplace replacement code

You have your utils.js with the classic document.querySelector shortcut:

function q(selector) {
    return document.querySelector(selector);
}

Lets say that the "assertion" is that this should be only called when we know the selector will always match a single element (for the other cases we simply call other functions)

We leave this "efficient" version, and we replicate the an error checking version of it in a new file utils.dev.js:

function q(selector) {
    const res = document.querySelectorAll(selector);
    if (res.length == 1) return res[0];
    throw `Found ${res.length} matches for '${selector}'`;
}

And then in the "build system" we specify one of the files based on the release mode.



done_

Friday, November 10, 2023

JavaScript: Generic selector proxied object

Lets create a thing to replace the very simple selector calls for id and classes.

First lets have simple selector for both the id and single class.

return document.getElementById(name) || 
    [...document.getElementsByClassName(name)]

Here we also return a single value when you pass an id and an array (expanding the default HTMLCollection) when a class is passed.

Now, if we want the make the whole thing more elegant like this:

elements.footer // == document.querySelector('#footer')
elements.button // == document.querySelectorAll('.button') 

We can use the a proxy handler to catch the selector like text that we defined above and return the elements.

const elements = new Proxy({}, {
    get(target, name) {
        return document.getElementById(name) || 
        	[...document.getElementsByClassName(name)];
    }
})

Where every time a property of elements must be deference the name of the property will end up in the get method in the name argument. 



_done

Tuesday, July 19, 2022

Html: Enter handler on input text field

Every single time you have a input text field and submit-like button next to it, at some point, you would like to bind the same action of the submit button to the press of the enter key.

It's trivial, but also it's simply better to just copy-paste it. So here its is:

function onenter(ele, f) {
	ele.addEventListener('keydown', function (e) {
		if (e.keyCode === 13) { f(e); e.preventDefault(); }
	})
}

And also while we are here, instead of using the-not-be-named lib, just use these:

function q(x) { return document.querySelector(x); }
function qa(x) { return [...document.querySelectorAll(x)]; }
function range(x) { return Array.from({length: x}, (v, i) => i); }

For more just go here.



done_

Wednesday, June 16, 2021

Javascript: Self call re-call interval set

 So we have the requestAnimationFrame, you pass a function and it called after a very specific while (irrelevant to the following).

Now lets see the basic structure:

function loop() {
    update()
    requestAnimationFrame(loop)
}
loop()

Ok now lets wrap the function and call it without calling it by name:

(function loop() {
    update()
    requestAnimationFrame(loop)
})()

Is there any way to remove the name of function and still pass it? There is a magical object called arguments which appears out of nothing every time a function is executed. And the member that we need is arguments.callee which is self reference to the function being executed. So we get rid of the name:

(function () {
    update()
    requestAnimationFrame(arguments.callee)
})()

And of course to maximize the coolness we put in a single line:

(function() { update(); requestAnimationFrame(arguments.callee) })()

Ok, this very cool, but is it worth it? Let's analyze what this code succeeds to do:

1. Confuses the next reader of the code.
2. Confuses also the 2nd reader.
3. Confuses also the 3rd reader.
...
N. Confuses also the N-th reader.

So you have to choose what is cooler: confusing no people or confusing up to infinite people? Comment below, like and subscribe.



done_



Sunday, July 21, 2019

Javascript: Do it like php!

So, I just wanted a simple thing... I had a static html page where I wanted to put some things in dynamically: a simple date at the start and an extended date in the middle of the text. (Also what is server side?)

Pure elegant javascript:

.... <span data-value="simple"></span> ....

<script>

var data = {
    simple: gen_simple(),
    ....
}

for (var i of document.querySelectorAll('[data-value]')) {
    i.innerHTML = data[i.getAttribute('data-value')];
}

<script>

Php infected javascript:

.... <script>document.write(gen_simple())</script> ....

plus if in 'I was never here' mode:

....
<script>
for (var i of document.querySelectorAll('script')) i.parentNode.removeChild(i);
</script>



done_

Wednesday, November 18, 2015

Javascript: Canvas circles

So we always start:

var canvas = document.getElementById("canvas");
var c = canvas.getContext("2d");

and we have the basic:

c.fillRect
c.fillText
c.strokeRect
c.strokeText

and for all other shapes we use paths

I use a lot of circles so why not add:

c.fillCircle
c.strokeCircle

We can do that by adding some functions to the prototype of the c with is the CanvasRenderingContext2D:

CanvasRenderingContext2D.prototype.fillCircle = function(x, y, r) {
  this.beginPath();
  this.arc(x, y, r, 0, 2 * Math.PI);
  this.fill();
};

CanvasRenderingContext2D.prototype.strokeCircle = function(x, y, r) {
  this.beginPath();
  this.arc(x, y, r, 0, 2 * Math.PI);
  this.stroke();
};


done_

Monday, November 16, 2015

HTML: Canvas background

To have a canvas as a html page background we need:

HTML:

<body onload="load()">
  <canvas id="canvas_back"></canvas>
  ...
</body>

CSS:

#canvas_back {
  position: fixed;
  top: 0px;
  left: 0px;
  z-index: -1;
}

JavaScript:

var c, w, h;

function load() {
  var canvas = document.getElementById("canvas_back");
  c = canvas.getContext("2d");

  window.addEventListener('resize', resize, false);
  resize();
}

function resize() {
  w = canvas.width = window.innerWidth;
  h = canvas.height = window.innerHeight;
  draw();
}

function draw() {
  // use c, w and h to draw the canvas
  ...
  requestAnimationFrame(draw);
}


Demo 1


done_

Wednesday, November 11, 2015

JavaScript: Local and Session storage

To store values to a browser we can use localStorage and sessionStorage just by:

localStorage["name"] = value;

and to get the values we just:

value = localStorage["name"];

The localStorage keeps the values for ever (probably).
The sessionStorage keeps the values until the page session ends.

For each domain our browser has a pair of these objects and not for each page.

To store objects without functions we use JSON:

localStorage["name"] = JSON.stringify(object);
object = JSON.parse(localStorage["name"]);


done_

Monday, November 9, 2015

JavaScript: jQuery selector

If we want to use JQuery ONLY for selecting elements like:

$(".item")

Why use a whole library, just:

document.querySelectorAll(".item")

or

function q(query) {
  return document.querySelectorAll(query);
}

q(".item")

Note: The only thing we gain from this is self-something.


continue_