这个框架使用十分的简略,简略应用就3步,实用于用原生写TV端需要的前端,即便素来没开发过TV端的看完根本应用也能够把握,十分好用!
github链接:https://github.com/simpleRobort/TV-Focus.js (感觉不错的麻烦github给个star,万分感激)

I.根本应用

1.事后写好页面,保障你所有可能获取焦点的dom元素领有一个对立结尾的id 个别为 "item?",其中?为数字,从0开始,上不封顶

        <!--     保障元素领有定位     --><div class="dom" id="item0" style="position: absolute;left:200px;top:200px;width:150px;height:150px">这是第个0dom</div><div class="dom" id="item1" style="position: absolute;left:400px;top:200px;width:150px;height:150px">这是第个1dom</div><div class="dom" id="item2" style="position: absolute;left:600px;top:200px;width:150px;height:150px">这是第个2dom</div><div class="dom" id="item3" style="position: absolute;left:200px;top:400px;width:150px;height:150px">这是第个3dom</div><div class="dom" id="item4" style="position: absolute;left:400px;top:400px;width:150px;height:150px">这是第个4dom</div><div class="dom" id="item5" style="position: absolute;left:600px;top:400px;width:150px;height:150px">这是第个5dom</div>

对应css:

        .focus {            border: 2px solid #0f0f0f; /*这里就是获取焦点的实现原理了,Focus.js会给获取焦点的元素增加一个名字叫做 focus 的class类*/        }

2.从源码里下载focus.js(点击下载),在你的html页面中引入

<script src="./focus.js"></script>

3.在引入之后创立一个script标签,new一个FOCUS对象并且传入参数

<script>        var vm = new FOCUS({            focusId: 'item3', // 页面首先获取焦点的dom元素的Id,不传默认item0            event: {                keyOkEvent: function (focusId) {                    console.log("点击了确认键,以后取得焦点的索引为:" + focusId)                    switch (focusId) {                        case 0:                                                       break                    }                },                keyBackEvent: function (focusId) {                    console.log("点击了返回键,以后取得焦点的索引为:" + focusId)                    switch (focusId) {                        case 6:                        case 7:                                                        break                    }                }            }        })</script>

到这里最简略的焦点挪动曾经被增加好了,你就能够关上页面看成果了

根本应用测试地址

II.进阶应用

1.应用后辈选择器显示暗藏图片与dom元素

根本应用里咱们只是简略的给focus增加了一个边框,十分的简便,然而当咱们须要通过焦点与否显示不同的图片的时候,只是简略的给focus增加边框并不够用,这时候就须要css的后辈选择器了

css:

.dom .select {  position: absolute; /*须要增加定位,不然会被未选中显示的内容挤下去*/  display: none; /*未被选中时暗藏选中才显示的内容*/}.dom .unselect {  display: block; /*未获取焦点时显示没被选中须要显示的内容*/}.focus .select {  display: block; /*获取焦点时显示被选中的须要显示的内容*/}.focus .unselect {  visibility: hidden; /*获取焦点时暗藏未被选中须要显示的内容*/}

html:

<!-- 以下图片为本地数据,如复制应用请批改--><div id="bg">    <div class="dom" id="item0" style="position: absolute;left:890px;top:100px;width:150px;height:150px">        <div class="unselect"><img src="../image/unselect/gengduo.png" alt=""></div>        <div class="select" style="left:0px;top:0px;"><img src="../image/select/gengduo.png" alt=""></div>    </div>    <div class="dom" id="item1" style="position: absolute;left:200px;top:200px;width:150px;height:150px">        <div class="unselect"><img src="../image/unselect/1.png" alt=""></div>        <div class="select" style="left:0px;top:0px;"><img src="../image/select/1.png" alt=""></div>    </div>    <div class="dom" id="item2" style="position: absolute;left:500px;top:200px;width:150px;height:150px">        <div class="unselect"><img src="../image/unselect/2.png" alt=""></div>        <div class="select" style="left:0px;top:0px;"><img src="../image/select/2.png" alt=""></div>    </div>    <div class="dom" id="item3" style="position: absolute;left:800px;top:200px;width:150px;height:150px">        <div class="unselect"><img src="../image/unselect/3.png" alt=""></div>        <div class="select" style="left:0px;top:0px;"><img src="../image/select/3.png" alt=""></div>    </div>    <div class="dom" id="item4" style="position: absolute;left:200px;top:400px;width:150px;height:150px">        <div class="unselect"><img src="../image/unselect/4.png" alt=""></div>        <div class="select" style="left:0px;top:0px;"><img src="../image/select/4.png" alt=""></div>    </div>    <div class="dom"  id="item5" style="position: absolute;left:500px;top:400px;width:150px;height:150px">        <div class="unselect"><img src="../image/unselect/5.png" alt=""></div>        <div class="select" style="left:0px;top:0px;"><img src="../image/select/5.png" alt=""></div>    </div>    <div class="dom"  id="item6" style="position: absolute;left:800px;top:400px;width:150px;height:150px">        <div class="unselect"><img src="../image/unselect/5.png" alt=""></div>        <div class="select" style="left:0px;top:0px;"><img src="../image/select/5.png" alt=""></div>    </div></div>

js:

   var vm = new FOCUS({        focusId: 'item3', // 页面首先获取焦点的dom元素的Id        event: {            keyOkEvent: function (focusId) {                console.log("点击了确认键,以后取得焦点的索引为:" + focusId)                switch (focusId) {                    case 0:                        break                }            },            keyBackEvent: function (focusId) {                console.log("点击了返回键,以后取得焦点的索引为:" + focusId)                switch (focusId) {                    case 6:                    case 7:                        break                }            }        }    })
应用后辈选择器示例地址

2.应用强制焦点变换 (forceMove)

实用的场景个别有两个:

1.你须要这个元素按某一个方向键不切换焦点或者切换到本人想要的焦点(哪怕隔了一座山哈哈)

2.你的ui设计稿十分的不法则(焦点默认的逻辑无奈满足需要,焦点默认挪动的逻辑是以dom的宽高地位发射一道射线,第一个触碰到的dom元素就会成为下一个焦点)

显然没有别的元素的话,这个两个元素无奈互相跳转,有人问我为什么不把断定范畴改大一点,我也试过,天然是解决了,然而有更多的问题呈现了,我这就不一一举例了哈哈,
回到正题,应用办法很简略,只须要在new FOCUS传入的对象里新增一个属性focusMove即可

var vm = new FOCUS({            focusId: 'item3',            forceMove: {                // 须要被强制的焦点id:[上,左,下,右]                item0: [-1,-1,"item1",-1],                item1: ["item0",-1,-1,-1],            }        })

forceMove也是一个对象,须要传入属性,属性值为一个数组,顺次为方向键上左下右,参数有三种取值,如下

取值形容
-1不做解决,随框架判断逻辑主动切换焦点
-2禁止挪动,即便对应的方向有焦点
其余dom的id强制挪动到对应的dom

3.事件处理 (event)

tv端除了上下左右方向键与数字键,还有其余的事件,这里也提供了api

 var vm = new FOCUS({        focusId: 'item3',        event: {            keyOkEvent: function (focusId) {                console.log("点击了确认键,以后取得焦点的索引为:" + focusId)                switch (focusId) {                    case 0:                        break                }            },            changeIndexBeforeFind: function (dir,focusId) {                // 两个传参(dir代表方向:上左下右顺次为0123,以后焦点id)                // Focus会在主动寻找下一个焦点前触发这个事件,如果这个函数返回了一个指定索引                // 那么框架就不会浪费时间去寻找下一个焦点,间接应用你返回的索引                // 例:                if (dir == 3 && focusId == 0) {                    return 2                }                 // 当在焦点索引为0的dom按下 右方向键,返回一个索引2,框架会放弃计算                // 间接让索引为2的获取焦点            },            changeIndexAfterFind: function (dir,focusId,nextId) {                 // 三个传参(前两个同上,nextId为计算实现的焦点,如果没有适合的焦点就会返回-1)                 // Focus会在寻找完焦点后触发这个事件,如果这个函数返回了一个指定索引                 // 那么框架就摈弃原本应该成为焦点的nextId,间接应用你返回的索引                        },                    }    })
事件名称(都是函数,如上)形容
keyNumberEvent遥控器数字点击,有两个传参:(对应的数字,以后获取焦点的索引)
keyOkEvent遥控器确认键,有一个传参(以后获取焦点的索引)
keyBackEvent遥控器返回键,有一个传参(以后获取焦点的索引)
focusEvent获取焦点后事件,有一个传参(以后获取焦点的索引)
unfocusEvent失去焦点后事件,有一个传参(失去焦点的索引)
darkFocusEvent获取暗焦点后事件,有一个传参(失去焦点的索引)
undarkFocusEvent失去暗焦点后事件,有一个传参(失去焦点的索引)
changeIndexBeforeFind按任意方向键后触发,详情见上图
changeIndexAfterFind按任意方向键后触发,详情见上图

4.二级以上页面 (pageState)

当页面有若干个焦点是在触发某一个事件才可能被获取焦点的,在事件未触发时不应该被获取焦点,如果通过下面的强制事件频繁的增加-2,那可太麻烦了,这时候就pageState就呈现了

应用办法:

 var vm = new FOCUS({        pageState: {                // 非凡焦点:页面索引(默认为1)                item4: 2,                item5: 2            },    })

5.办法 (methods)

为了尽量使页面的外围代码保留在FOCUS传参内,增加了相似vue的methods来不便代码治理

应用办法:

 var vm = new FOCUS({        methods: {                    handleTest: function () {                        console.log("你点击了methods")                    }                },         event: {                  keyOkEvent: function (focusId) {                      this.handleTest()                  }              }    })

传参时传入一个methods对象,用来保留办法,this指向Focus,也通过this.办法名来调用methods外部办法

methods示例地址

5.暗焦点 (darkFocus)

tv端常常会有一个需要,页面上会有多个焦点,比如说一个节目,你可能会须要其余的焦点来示意以后所属于的分类,咱们称之为暗焦点

 var vm = new FOCUS({        darkFocus:[[1,0,2,3,4],[5,6,7,8]], //暗焦点列表一个数组蕴含多个数组,参数为id后的索引,代表这几个dom为一块暗焦点,并且数组第一个索引为默认选中的暗焦点        darkGroup:[true,true], // 长度与darkFocus对应,代表每次进入暗焦点列表时,是否始终让这个列表的暗焦点被选中        darkClass: "active", // 暗焦点被增加的class ,默认就是 active        event: {            darkFocusEvent: function (id) {                // 你有可能会须要在焦点切换时依据以后的分类渲染新数据,                // 咱们心愿你应用的是这个事件而不是focusEvent                // 这是为了防抖,在暗焦点没扭转时反复获焦不会反复触发这个事件                console.log("获取暗焦点",id)             },            undarkFocusEvent: function (id) {                console.log("失落暗焦点",id)            },            focusEvent: function (id) {                console.log("获取焦点",id)            },            unfocusEvent: function (id) {                console.log("失落焦点",id)            },        }    })

6.使用各api实现一个tv端常见demo (demo)

tv最多的就是多级栏目的需要,在焦点切换时,对应的子列表,子节目都要发生变化,本文章次要介绍框架的应用,
故具体内容可下载源码与focus文件理解

demo地址

7.生命周期 (生命周期)

按目前的需要引入了一个初始创立时的生命周期created

应用形式:

 var vm = new FOCUS({         created: function (next) {             this.addDiv()             next() //必须调用, 不调用无奈库就不执行初始化         },         methods: {             addDiv: function () {                 var div = document.createElement("div")                 div.classList = "dom"                 div.id = "item6"                 var newContent = document.createTextNode("生命周期增加的dom");                  div.appendChild(newContent);                  document.body.appendChild(div);             }         }     })
demo地址
周期名称传参形容
creatednext提供一个next办法,在调用后库才会持续抓取页面的焦点并且初始化,此时能拜访methods里的办法

III new FOCUS传参

var vm = new FOCUS({ })

传参为一个对象,其中对象外部的属性如下:

属性名称类型形容
domIdNamestring对立id,默认为"item",如心愿对立id为 ("focusDom0"、"focusDom1"...),即该参数值为 "focusDom"
focusIdstring须要首先聚焦的id,默认索引为0的元素
focusClassstring聚焦dom减少的class,默认为"focus"
pageStateint设置页面等级,详情参考II.4
forceMoveobject批改dom的方向键逻辑,详情参考II.2
eventobject按键处理事件,详情参考II.3
methodsobject办法保留,相似vue的methods,详情参考II.5
darkFocusarray暗焦点,在焦点在别处时仍旧显示非凡款式,每个数组第一个索引为默认选中的暗焦点,详情参考II.6
darkClassstring暗焦点被增加的class ,默认就是 active,详情参考II.6
darkGrouparray长度与darkFocus对应,代表每次进入暗焦点列表时,是否始终让这个列表的暗焦点被选中,详情参考II.6
unFocusArrarray数组,数组能够有多个id索引,代表初始不容许被选中的焦点,之后可用上面介绍的 openFocus 解除禁止被选中

IV 框架的Api

应用办法:

在实例外部应用: 示例:this.requireFocus(0)

在实例内部应用: 示例:vm.requireFocus(0) (vm为实例对象)

        var vm = new FOCUS({            event: {                keyOkEvent: function (focusId) {                    this.requireFocus(6) // 在实例外部应用                }            }        })        vm.requireFocus(6) // 在实例内部应用
Api名称传参数量传参形容
requireFocus1number使元素获取焦点,传参为索引值,例(使id为"item2"的元素获取焦点):this.requireFocus(2)
log4(后三个参数可不传)打印内容,字体大小(默认16px), 文字色彩(默认红色),背景色彩(默认彩色)tv端无控制台,所以须要此api显示打印信息
getDom1int依据传参索引返回元素
getFocus0返回以后焦点索引
getParam3字段名:字符串 默认值 地址:默认以后地址解析url传参
gotoPage1url地址单纯的跳转url,可能会在须要跳转前发送申请而存在
getFocusDom0返回以后焦点dom元素
stopFocus1数组:内容为一个或多个dom索引使数组内的焦点无奈被获取焦点
openFocus1数组:内容为一个或多个dom索引使数组内的焦点从stopFocus内移除,可能获取焦点
refresh0调用后库会抛弃原来的焦点汇合,从新去抓取页面上的焦点

V 版本日志

版本号更新内容日期
1.0.6提供一个初始化的生命周期,为了适配页面初始化时要增加dom的需要2022-5-19
1.0.5增加焦点切换前后事件,动静批改焦点获取与否,减少框架的灵活性2022-3-8
1.0.4增加暗焦点相干事件,以及暗焦点防抖等解决2022-3-7
1.0.3增加methods传参,用来优化代码标准,增加getparam办法,获取url参数2022-3-3
1.0.2增加打印调试api,以及readme.md排版更新,版本日志2021-12-27
1.0.1增加二级以上页面,失焦获焦事件2021-12-21
1.0.0具备tv端焦点框架根本需要2021-12-20

其余

如果这个框架可能被很多应用到,我想我会十分的开心,如果你有什么感觉框架须要减少的好的倡议,我很荣幸可能晓得,这是我的联系方式,请表明来意,心愿您能给我一个点赞,这是对我最大的激励

vx:DoubleU-_

QQ:1026990903