8

I'm looking to create a custom event in HTML, JS.

<input type="text" oncustombind="foo(event);" />

How can I create one such? 'oncustombind' is the custom event I want to create. I should be able to call the function/code defined in the oncustombind attribute. Also, I need to pass some data to the event object.

I don't want to use any libraries such as jquery, YUI.

Any help would be deeply appreciated.

varunvs
  • 875
  • 12
  • 23
  • 2
    As an aside inline javascript in HTML is a big dirty hack. Don't do it. – Raynos Oct 28 '11 at 10:22
  • 2
    Since the question was posted times have changed. Currently web components are becoming a viable way to replace js frameworks. Having inline custom events would be actually really useful for writing code that can be easily read (similar to angular / react). One nice trick is to share the `this` context of the web component with the chidlren dom element using `Object.assign`. In this way any selected Dom element can have access to methods defined in the web components class. It would be even nicer to have access to custom events from inline custom event handlers. – Adrian Moisa Dec 10 '17 at 08:46

2 Answers2

11

You want a CustomEvent

They should be easy to work with but browser support is poor. However the DOM-shim should fix that.

var ev = new CustomEvent("someString");
var el = document.getElementById("someElement");
el.addEventListener("someString", function (ev) {
    // should work
});
el.dispatchEvent(ev);
Raynos
  • 166,823
  • 56
  • 351
  • 396
5

It's bad practice to use new Function and with, but this can be accomplished as follows: http://jsfiddle.net/pimvdb/72GwE/13/.

function trigger(elem, name, e) {
    var func = new Function('e',

      'with(document) {'
    + 'with(this) {'
    + elem.getAttribute('on' + name)
    + '}'
    + '}');

    func.call(elem, e);
}

With the following HTML:

<input type="text" oncustombind="console.log(e, type, getElementById);" id="x">

then trigger the event like:

trigger(document.getElementById('x'), 'custombind', {foo: 123});
pimvdb
  • 151,816
  • 78
  • 307
  • 352
  • 1
    @Raynos: What would you use to make `window`, `document`, `event` and `e` to be in the scope? There is no better way than `with`... – pimvdb Oct 28 '11 at 10:17
  • in the scope of what? `window`, `document`, `elem` and `e` are already in scope. – Raynos Oct 28 '11 at 10:20
  • @Raynos: In HTML event attributes you can obtain attributes and `document`'s functions automatically, e.g. `getElementById` without `document.` prepended. – pimvdb Oct 28 '11 at 10:21
  • @pimvb ... That's why we don't use inline event handlers and dirty hacks. Everyone knows javascript in HTML is a big no-no. – Raynos Oct 28 '11 at 10:22
  • your "getting it in scope" hack [doesn't even work](http://jsfiddle.net/72GwE/9/) – Raynos Oct 28 '11 at 10:24
  • your code breaks in ES5-strict. `with` was deprecated for a reason – Raynos Oct 28 '11 at 10:46
  • @Raynos: Then I guess there is no manual way to make `document`'s properties available in the scope. – pimvdb Oct 28 '11 at 10:49