db-lgtv-focus-engine
Version:
the Best TV focus engine
78 lines (77 loc) • 2.56 kB
JavaScript
class Trunk {
constructor(engine, el) {
// 构建Leaf
this.engine = engine
this.id = el.getAttribute('db-id') || window.getIdByDom(el)
this.el = el
this.cacheable = el.hasAttribute('db-cacheable') ? (el.getAttribute('db-cacheable') || 'focus') : false
this.left_exit = el.getAttribute('db-left-forbid') === null
this.right_exit = el.getAttribute('db-right-forbid') === null
this.top_exit = el.getAttribute('db-top-forbid') === null
this.bottom_exit = el.getAttribute('db-bottom-forbid') === null
this.rect = el.getBoundingClientRect()
this.initLeafs()
}
// 初始化叶子
initLeafs() {
this.child = []
this.engine.leaf_pool.forEach(leaf => {
// 非枝上叶子元素
if (!this.el.contains(leaf.el)) {
return
}
this.child.push(leaf)
// 孤叶子元素
if (!leaf.parent) {
leaf.parent = this
return
}
// 争夺叶子元素
if (leaf.parent.el.contains(this.el)) {
this.parent = leaf.parent
leaf.parent = this
return
} else {
leaf.parent.parent = this
}
})
// 默认缓存第一个
setTimeout(() => {
// trunk中没有缓存
if (this.cacheable && !this.cache && this.child.length > 0) {
let default_cache_leaf = this.child.find(leaf => leaf.el.hasAttribute('db-default-cache')) || this.child[0]
default_cache_leaf.cache()
}
}, 0)
// freeze 叶子组件
if (this.el.hasAttribute('db-freeze')) this.freeze()
}
focus() {
let focused_leaf = this.engine.findFocusedLeaf()
if (focused_leaf && focused_leaf.parent === this) return
this.el.setAttribute('db-child-focus', '')
this.el.dispatchEvent(new Event("focus"))
}
blur() {
this.el.removeAttribute('db-child-focus')
this.el.dispatchEvent(new Event("blur"))
}
freeze() {
this.child.forEach(leaf => leaf.freeze({
render: false
}))
this.engine.render()
}
unfreeze() {
this.child.forEach(leaf => leaf.unfreeze({
render: false
}))
this.engine.render()
}
clear() {
this.child.forEach(_i => {
_i.el.removeAttribute('db-focus')
})
}
}
export default Trunk