Table of contents

Events handlers binding

In this example:

bindDOM(`<button onclick="console.log('clicked')">Click</button>`);

we're rebinding default click handler. When clicking on the button in the browser we'll get an error: ReferenceError: "console" is not defined.. Reminder - there is no implicit global scope in Vanillin.

ReferenceError is easy to fix:

bindDOM(`<button onclick="console.log('clicked')">Click</button>`, console.log, console.error, { console });

If you want for any reason to operate on global scope - not recommended in regular case - pass window itself:

bindDOM(`<button onclick="console.log('clicked')">Click</button>`, console.log, console.error, window);

Event handlers on HTML elements are rebound automatically using addEventListener for every attribute which name starts with on - rest of the name after on prefix is the event name:

bindDOM(
  `<input onkeydown="console.log('down', event)" onkeyup="console.log('up', event)" />`,
  console.log,
  console.error,
  { console }
);

Both onkeydown and onkeyup were bound with Vanillin. Other thing to note: event variable in handlers. It works the same way as in standard DOM. DOM event is bound to event reference. Try to run this example without Vanillin in pure DOM. Output in console will be the same.

Other thing the browser does is it bounds this to element on which an event occured. Vanillin copies it as well:

bindDOM(
  `<input onkeydown="console.log('down', event, this)" onkeyup="console.log('up', event, this)" />`,
  console.log,
  console.error,
  { console }
);

this will be bound to HTMLInputElement element.

Good design note: if inline handlers become to long, move them to a function:

bindDOM(
  `<input onkeydown="onkey('down', event, this)" onkeyup="onkey('up', event, this)" />`,
  console.log,
  console.error,
  {
    console,
    onkey(type, event, element) {
      console.log(type, event, element);
    }
  }
);

In this example they aren't too long, but you should get the point. What's more, some users may not like any logic in HTML so they should use functions everywhere they can. They can also manually use addEventListener to bind a metaFunction.

Example:

const button = document.createElement("button");
button.textContent = "Click me";
metaesEval(
  (event) => console.log("metaFunction was called as event handler with event: ", event),
  (handler) => button.addEventListener("click", handler),
  console.error,
  { console }
);
document.body.appendChild(button);

This will be useful when bridging existing DOM with metaES context.