@antv/x6
Version:
JavaScript diagramming library that uses SVG and HTML for rendering.
85 lines (73 loc) • 2.03 kB
text/typescript
import { debounce } from './util'
import { Listener, Sensor } from '../types'
export function createSensor(element: Element): Sensor {
let sensor: HTMLObjectElement | null = null
let listeners: Listener[] = []
const create = () => {
if (getComputedStyle(element).position === 'static') {
const style = (element as HTMLElement).style
style.position = 'relative'
}
const obj = document.createElement('object')
obj.onload = () => {
obj.contentDocument!.defaultView!.addEventListener('resize', trigger)
trigger()
}
obj.style.display = 'block'
obj.style.position = 'absolute'
obj.style.top = '0'
obj.style.left = '0'
obj.style.height = '100%'
obj.style.width = '100%'
obj.style.overflow = 'hidden'
obj.style.pointerEvents = 'none'
obj.style.zIndex = '-1'
obj.style.opacity = '0'
obj.setAttribute('tabindex', '-1')
obj.type = 'text/html'
element.appendChild(obj)
// for ie, should set data attribute delay, or will be white screen
obj.data = 'about:blank'
return obj
}
const trigger = debounce(() => {
listeners.forEach((listener) => listener(element))
})
const bind = (listener: Listener) => {
if (!sensor) {
sensor = create()
}
if (listeners.indexOf(listener) === -1) {
listeners.push(listener)
}
}
const destroy = () => {
if (sensor && sensor.parentNode) {
if (sensor.contentDocument) {
sensor.contentDocument!.defaultView!.removeEventListener(
'resize',
trigger,
)
}
sensor.parentNode.removeChild(sensor)
sensor = null
listeners = []
}
}
const unbind = (listener: Listener) => {
const idx = listeners.indexOf(listener)
if (idx !== -1) {
listeners.splice(idx, 1)
}
// no listener, and sensor is exist then destroy the sensor
if (listeners.length === 0 && sensor) {
destroy()
}
}
return {
element,
bind,
destroy,
unbind,
}
}