@riophae/vue-treeselect
Version:
A multi-select component with nested options support for Vue.js
68 lines (56 loc) • 1.64 kB
JavaScript
import watchSizeForBrowsersOtherThanIE9 from 'watch-size'
import { removeFromArray } from './removeFromArray'
let intervalId
const registered = []
const INTERVAL_DURATION = 100
function run() {
intervalId = setInterval(() => {
registered.forEach(test)
}, INTERVAL_DURATION)
}
function stop() {
clearInterval(intervalId)
intervalId = null
}
function test(item) {
const { $el, listener, lastWidth, lastHeight } = item
const width = $el.offsetWidth
const height = $el.offsetHeight
if (lastWidth !== width || lastHeight !== height) {
item.lastWidth = width
item.lastHeight = height
listener({ width, height })
}
}
function watchSizeForIE9($el, listener) {
const item = {
$el,
listener,
lastWidth: null,
lastHeight: null,
}
const unwatch = () => {
removeFromArray(registered, item)
if (!registered.length) stop()
}
registered.push(item)
// The original watch-size will call the listener on initialization.
// Keep the same behavior here.
test(item)
run()
return unwatch
}
export function watchSize($el, listener) {
// See: https://stackoverflow.com/a/31293352
const isIE9 = document.documentMode === 9
// watch-size will call the listener on initialization.
// Disable this behavior with a lock to achieve a clearer code logic.
let locked = true
const wrappedListener = (...args) => locked || listener(...args)
const implementation = isIE9
? watchSizeForIE9
: watchSizeForBrowsersOtherThanIE9
const removeSizeWatcher = implementation($el, wrappedListener)
locked = false // unlock after initialization
return removeSizeWatcher
}