src/ListenerOrganizerMixin.js
import $ from 'jquery'
import Observable, { unByKey } from 'ol/Observable'
class DOMListener {
constructor (element) {
this.element = element
}
on (event, listener, useCapture) {
this.event = event
this.listener = listener
this.useCapture = useCapture
this.element.addEventListener(event, listener, useCapture)
}
once (event, listener, useCapture) {
const that = this
this.on(event, function (...args) {
listener.apply(this, args)
that.detach()
}, useCapture)
}
detach () {
this.element.removeEventListener(this.event, this.listener, this.useCapture)
}
}
class JQueryListener {
constructor (element) {
this.element = element
}
on (event, listener) {
this.event = event
this.listener = listener
this.element.on(event, listener)
}
once (event, listener) {
this.event = event
this.listener = listener
this.element.one(event, listener)
}
detach () {
this.element.off(this.event, this.listener)
}
}
class OLListener {
constructor (element) {
this.element = element
}
on (event, listener) {
this.event = event
this.key_ = this.element.on(event, listener)
}
once (event, listener) {
this.event = event
this.key_ = this.element.once(event, listener)
}
detach () {
unByKey(this.key_)
}
}
export class ListenerOrganizerMixin {
initialize () {
this.organizedListeners_ = []
}
static getTypeListener (element) {
if (element instanceof Observable) {
return new OLListener(element)
}
if (element instanceof $) {
return new JQueryListener(element)
}
if (element.addEventListener) {
return new DOMListener(element)
}
throw new Error('no suitable listener interface found!')
}
listenAt (elements) {
elements = Array.isArray(elements) ? elements : [elements]
const returnObj = {
on: (event, listener, useCapture) => {
for (const element of elements) {
const tListener = ListenerOrganizerMixin.getTypeListener(element)
tListener.on(event, listener, useCapture)
this.organizedListeners_.push(tListener)
}
return returnObj
},
once: (event, listener, useCapture) => {
for (const element of elements) {
const tListener = ListenerOrganizerMixin.getTypeListener(element)
tListener.once(event, listener, useCapture)
this.organizedListeners_.push(tListener)
}
return returnObj
}
}
return returnObj
}
detachFrom (element, event) {
let listeners = this.organizedListeners_.filter(l => l.element === element)
if (event) {
listeners = listeners.filter(l => l.event === event)
}
for (const listener of listeners) {
listener.detach()
this.organizedListeners_.splice(this.organizedListeners_.indexOf(listener), 1)
}
}
detachAllListeners () {
for (const listener of this.organizedListeners_) {
listener.detach()
}
this.organizedListeners_ = []
}
}