error-message
success-message
saving-message
warning-message
JavaScript must be enabled.
There was an error retrieving this content.
The content could not be found.
An implementation of WHATWG EventTarget interface, plus few extensions.
EventTarget
constructor that can inherit for your custom object.obj.onclick
).import {EventTarget, defineEventAttribute} from "event-target-shim"
class Foo extends EventTarget {
// ...
}
// Define `foo.onhello` property.
defineEventAttribute(Foo.prototype, "hello")
// Use
const foo = new Foo()
foo.addEventListener("hello", e => console.log("hello", e))
foo.onhello = e => console.log("onhello:", e)
foo.dispatchEvent(new CustomEvent("hello"))
Use npm to install then use a bundler.
npm install event-target-shim
Or download from dist
directory.
import {EventTarget, defineEventAttribute} from "event-target-shim"
// or
const {EventTarget, defineEventAttribute} = require("event-target-shim")
// or UMD version defines a global variable:
const {EventTarget, defineEventAttribute} = window.EventTargetShim
https://dom.spec.whatwg.org/#interface-eventtarget
Register an event listener.
type
is a string. This is the event name to register.callback
is a function. This is the event listener to register.options
is a boolean or an object { capture?: boolean, passive?: boolean, once?: boolean }
. If this is a boolean, it's same meaning as { capture: options }
.
capture
is the flag to register the event listener for capture phase.passive
is the flag to ignore event.preventDefault()
method in the event listener.once
is the flag to remove the event listener automatically after the first call.Unregister an event listener.
type
is a string. This is the event name to unregister.callback
is a function. This is the event listener to unregister.options
is a boolean or an object { capture?: boolean }
. If this is a boolean, it's same meaning as { capture: options }
.
capture
is the flag to register the event listener for capture phase.Dispatch an event.
event
is a Event object or an object { type: string, [key: string]: any }
. The latter is non-standard but useful. In both cases, listeners receive the event as implementing Event interface.Define an event attribute (e.g. onclick
) to proto
. This is non-standard.
proto
is an object (assuming it's a prototype object). This function defines a getter/setter pair for the event attribute.type
is a string. This is the event name to define.For example:
class AbortSignal extends EventTarget {
constructor() {
this.aborted = false
}
}
// Define `onabort` property.
defineEventAttribute(AbortSignal.prototype, "abort")
Define a custom EventTarget
class with event attributes. This is non-standard.
types
is a string or an array of strings. This is the event name to define.For example:
// This has `onabort` property.
class AbortSignal extends EventTarget("abort") {
constructor() {
this.aborted = false
}
}
https://jsfiddle.net/636vea92/
const {EventTarget, defineEventAttribute} = EventTargetShim
// Define a derived class.
class Foo extends EventTarget {
// ...
}
// Define `foo.onhello` property.
defineEventAttribute(Foo.prototype, "hello")
// Register event listeners.
const foo = new Foo()
foo.addEventListener("hello", (e) => {
console.log("hello", e)
})
foo.onhello = (e) => {
console.log("onhello", e)
}
// Dispatching events
foo.dispatchEvent(new CustomEvent("hello", { detail: "detail" }))
import { EventTarget, defineEventAttribute } from "event-target-shim";
// Define events
type FooEvents = {
hello: CustomEvent
}
type FooEventAttributes = {
onhello: CustomEvent
}
// Define a derived class.
class Foo extends EventTarget<FooEvents, FooEventAttributes> {
// ...
}
// Define `foo.onhello` property's implementation.
defineEventAttribute(Foo.prototype, "hello")
// Register event listeners.
const foo = new Foo()
foo.addEventListener("hello", (e) => {
console.log("hello", e.detail)
})
foo.onhello = (e) => {
console.log("onhello", e.detail)
}
// Dispatching events
foo.dispatchEvent(new CustomEvent("hello", { detail: "detail" }))
Unfortunately, both FooEvents
and FooEventAttributes
are needed because TypeScript doesn't allow the mutation of string literal types. If TypeScript allowed us to compute "onhello"
from "hello"
in types, FooEventAttributes
will be optional.
This EventTarget
type is compatible with EventTarget
interface of lib.dom.d.ts
.
By default, methods such as addEventListener
accept unknown events. You can disallow unknown events by the third type parameter "strict"
.
type FooEvents = {
hello: CustomEvent
}
class Foo extends EventTarget<FooEvents, {}, "strict"> {
// ...
}
// OK because `hello` is defined in FooEvents.
foo.addEventListener("hello", (e) => {
})
// Error because `unknown` is not defined in FooEvents.
foo.addEventListener("unknown", (e) => {
})
However, if you use "strict"
parameter, it loses compatibility with EventTarget
interface of lib.dom.d.ts
.
dispatchEvent()
methodTypeScript cannot infer the event type of dispatchEvent()
method properly from the argument in most cases. You can improve this behavior with the following steps:
"strict"
. This prevents inferring to dispatchEvent<string>()
.type
property of event definitions stricter.type FooEvents = {
hello: CustomEvent & { type: "hello" }
hey: Event & { type: "hey" }
}
class Foo extends EventTarget<FooEvents, {}, "strict"> {
// ...
}
// Error because `detail` property is lacking.
foo.dispatchEvent({ type: "hello" })
https://jsfiddle.net/522zc9de/
// Define a derived class.
function Foo() {
EventTarget.call(this)
}
Foo.prototype = Object.create(EventTarget.prototype, {
constructor: { value: Foo, configurable: true, writable: true }
// ...
})
// Define `foo.onhello` property.
defineEventAttribute(Foo.prototype, "hello")
// Register event listeners.
var foo = new Foo()
foo.addEventListener("hello", function(e) {
console.log("hello", e)
})
foo.onhello = function(e) {
console.log("onhello", e)
}
// Dispatching events
function isSupportEventConstrucor() { // IE does not support.
try {
new CusomEvent("hello")
return true
} catch (_err) {
return false
}
}
if (isSupportEventConstrucor()) {
foo.dispatchEvent(new CustomEvent("hello", { detail: "detail" }))
} else {
var e = document.createEvent("CustomEvent")
e.initCustomEvent("hello", false, false, "detail")
foo.dispatchEvent(e)
}
Contributing is welcome ❤️
Please use GitHub issues/PRs.
npm install
installs dependencies for development.npm test
runs tests and measures code coverage.npm run clean
removes temporary files of tests.npm run coverage
opens code coverage of the previous test with your default browser.npm run lint
runs ESLint.npm run build
generates dist
codes.npm run watch
runs tests on each file change.JavaScript must be enabled.
There was an error retrieving this content.
The content could not be found.
JavaScript must be enabled.
There was an error retrieving this content.
The content could not be found.
Confirm message?