最近做了个tv端的项目,是webview套的vue项目,电视上还不能调试,可把我难坏了。

首当其冲的就是按键控制,包括上下左右,确定,返回,home键等。

查了一下它们的keycode:

36home,37左,38上,39右,40下 ,13确定, 8(也有的是4)返回。

返回键默认是跳出app,如果不灵,需要app端配合写回退方法。

写了一个公共方法(要用到jquery):

import router from '../router'
var buttons = [], //需要聚焦的元素集合
    focusIndex = 0, //当前聚焦元素
    focusLen = 0 //需要聚焦的元素总个数

function initFocus(name, curr) {
    buttons = $('.' + name); //获取传入class名的需要聚焦的元素
    focusLen = buttons.length; //个数
    focusIndex = curr; //当前聚焦元素
    buttons.eq(focusIndex).addClass('focus'); //为当前聚焦元素添加聚焦样式class
    buttons.not(":eq(" + focusIndex + ")").removeClass('focus');//为非当前聚焦元素移除聚焦样式class
}

//绑定方法, focusTopArray是按上键时的矩阵数组,如:[[1,0],[0,1]], focusBottomArray是按下键时的矩阵数组,左右一般就是加减,我就没加上,可以看情况另外扩写
//导航和swiper是例外情况,另加的
function bindFocus(id, focusTopArray, focusBottomArray) {
    document.onkeyup = function(e) {
        var key = e.which; //获取keycode
        //36home 37左 38上 39右 40下 13确定 8返回
        if (key == 37) {
            focusIndex =
                focusIndex - 1 < 0 ? 0 : focusIndex - 1;
            //样式操作
            buttons.eq(focusIndex).addClass('focus');
            buttons.not(":eq(" + focusIndex + ")").removeClass('focus');
            
            //导航
            if (buttons.eq(focusIndex).hasClass('top-btn')) {
                buttons.eq(focusIndex).trigger("click");
            }
            //swiper
            if (buttons.eq(focusIndex).hasClass('lesson-item')) {
                $('.slide-index').val(focusIndex);
                $('.to-slide').trigger('click')
            }
        } else if (key == 39) {
            focusIndex =
                focusIndex + 1 > focusLen ? focusIndex : focusIndex + 1;

            //样式操作
            buttons.eq(focusIndex).addClass('focus');
            buttons.not(":eq(" + focusIndex + ")").removeClass('focus');
            //导航
            if (buttons.eq(focusIndex).hasClass('top-btn')) {
                buttons.eq(focusIndex).trigger("click");
            }
            //swiper
            if (buttons.eq(focusIndex).hasClass('lesson-item')) {
                $('.slide-index').val(focusIndex);
                $('.to-slide').trigger('click')
            }
        } else if (key == 38) {
            if (focusTopArray) {
                var index = focusIndex;
                focusTopArray.forEach(element => {
                    if (element[0] == focusIndex) {
                        index = element[1];
                    }
                });
                focusIndex = index;
            } else {
                focusIndex =
                    focusIndex - 1 < 0 ? focusLen - 1 : focusIndex - 1;
            }

            //样式操作
            buttons.eq(focusIndex).addClass('focus');
            buttons.not(":eq(" + focusIndex + ")").removeClass('focus');
            //导航
            if (buttons.eq(focusIndex).hasClass('top-btn')) {
                buttons.eq(focusIndex).trigger("click");
            }
            //swiper
            if (buttons.eq(focusIndex).hasClass('lesson-item')) {
                $('.slide-index').val(focusIndex);
                $('.to-slide').trigger('click')
            }
        } else if (key == 40) {
            if (focusBottomArray) {
                var index = focusIndex;
                focusBottomArray.forEach(element => {
                    if (element[0] == focusIndex) {
                        index = element[1];
                    }
                });
                focusIndex = index;
            } else {
                focusIndex =
                    focusIndex + 1 > focusLen - 1 ? 0 : focusIndex + 1;
            }
            //样式操作
            buttons.eq(focusIndex).addClass('focus');
            buttons.not(":eq(" + focusIndex + ")").removeClass('focus');
            //导航
            if (buttons.eq(focusIndex).hasClass('top-btn')) {
                buttons.eq(focusIndex).trigger("click");
            }
            //swiper
            if (buttons.eq(focusIndex).hasClass('lesson-item')) {
                $('.slide-index').val(focusIndex);
                $('.to-slide').trigger('click')
            }
        } else if (key == 36) {
            router.push({ path: "/" });
        } else if (key == 8 || key == 4) {
             if (window.history.length <= 1) {
                 router.push({ path: "/" });
                 return false;
             } else {
                 router.go(-1);
             }
        } else if (key == 13) {
            buttons.eq(focusIndex).trigger("click");
        } else {
            return false;
        }
    }
}
export {
    initFocus,
    bindFocus,
}

使用:

initFocus("focus-btn", 0);
bindFocus("index", this.focusTopArray, this.focusBottomArray);
//如果元素是死的就放在mounted里
//如果是另外渲染的就放在请求后的nextTick里
//内容比如列表个数变化或者tab切换时需要重新调用

还有一个问题困扰我,就是切换很快的时候莫名其妙会弹出键盘,明明我使用的都不是有输入功能的标签,最后只能让app端把键盘弹出事件禁掉了。

如果有大佬知道是怎么回事欢迎评论告知,多谢啦。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐