在IPTV高清页面中,小窗口播放视频时,在某些机顶盒上(如高清中兴、高清大亚4904)会出现焦点无法移动现象,即按键无响应。被这个bug困扰了很久,虽然我知道解决方法,但只知其然,不知其所以然。今天做了实验,结果分析如下:

  当页面调用视频播放方法时,我们知道代码所做的实际工作是将含有视频ID、视频窗口位置、视频窗口大小等参数拼接在url里,赋值给用于播放视频的iframe的src,此时会在当前页面运行播放控件(我猜想可能是这样。当然这个播放控件只在IPTV机顶盒上得到支持是确定的,在PC端会报错,因为PC端浏览器并不识别代码用于播放视频所创建的对象),这时该iframe处于获得焦点状态,即页面当前焦点在此iframe上。当我们操作遥控器来移动焦点,这时,在中兴、大亚4904高清机顶盒上表现为焦点不移动。

  原因是该iframe获得的焦点并没有被去掉,或者说其焦点无法转移到页面其他元素上,故而做遥控器方向键按键操作时,页面无响应。

  现在来证明这个结论。

  在html页面中,很多元素可以获得和失去焦点,如a、img 、input等有href或src属性的标签。在高清页面中,元素(这里指我们实际使用的div标签)获得的焦点并非html页面中的焦点,而是通过javascript改变其css样式用以标注当前位置,我们自称其为焦点,这是一个表象,用于告诉用户(实际操作者)将要操作的对象在页面所处位置,并非是处于.focus状态,与上述标签(红色标注)所获得的焦点性质不同。可获得焦点的元素在BOM中可以通过.focus方法来获得焦点,部分浏览器会在获得焦点的元素周围显示一个虚线框,此时可以通过键盘上的Tab键来切换焦点。

  也就是说,用于播放视频的iframe所获得焦点与我们在IPTV页面中所描述的焦点不是同一回事。前者是html页面中的真实焦点,后者是一个标记,我们用于在页面(最终是在电视上)定位的视觉标记,其切换实际是通过javascript改变css样式,产生颜色的较大变化,达到一个视觉效果,用以告诉用户当前将要操作的对象所处位置。

  既然此焦点非彼焦点,那么页面元素在被切换焦点时,也就是在发生失去焦点或者获得焦点事件时的处理方式就不同。页面中那个真实的焦点只能被切换到可以接受它的元素上,也就是那些具有href或者src属性的标签上,当页面上不存在这些元素时,或者这些元素距离较远时,焦点就不会得到正常切换,会一直保持在原来位置不变,此时页面处于焦点锁死状态(自己猜测)。

  知道了原因,我们就找到了解决最开始那个问题的思路。

  我们可以有两种方法来解决:

  方法一、向页面添加可以接受那个真实焦点的元素,比如a、img、input等标签,为了避免添加的标签影响页面美观,可以将其宽高设置为0,相当于在页面影藏掉,你也可以对它设置display:none样式,注意,它虽然被影藏,但却实实在在的存在于页面中。当然这里最好将用于接受真实焦点的标签添加到那个抱着真实焦点舍不得放的元素的附近,远了不行,为了把焦点送给你,人家还要买张火车票,你说人家愿不愿意呢。当然,在有些浏览器中(这里实际是高清机顶盒),那个拥有真实焦点的元素(也就是那个用于播放视频的iframe)此时会表现得比较慷慨,可以自掏腰包买机票只为千里送焦点。

  方法二、将那个拥有真实焦点的元素附近的元素改为可以接受页面真实焦点的元素。这里说的有点拗口,比如,此时你希望将iframe的焦点移动到它附近的那个div上,那么你可以将此div设置为可以接受页面真实焦点的元素。如何设置?你可以对该div追加一个tabIndex属性,这个属性值可以是1到32767间的任一值,这时就把这个div加入到TAB键的序列中。

  这里简单介绍下焦点在被设置tabIndex属性的元素间的移动规则,当浏览者使用Tab键在页面中移动焦点时,焦点将首先移动到具有最小tabIndex属性值的元素上,最后在具有最大tabIndex属性值的元素上结束移动。如果有两个元素的tabIndex属性相同,则以元素在html代码中出现的顺序为准。 默认的tabIndex属性为 0 ,将排列在所有指定tabIndex的元素之后。所以对于上面的方法二,最好将div的tabIndex属性值设置为1而不是0。而若把tabIndex属性设为一个负值(如tabIndex="-1"),那么这个元素将被排除在TAB键的序列之外。

  现在回到我们最开始要解决的问题。

  对于上面的方法一,我们使用a标签在高清中兴、高清大亚4904机顶盒上是可行的,我们也是一直这么做的,这样处理后,在其他原来就可以正常移动焦点的高清机顶盒上也没有造成不支持的影响。我们没有测试img和input标签,但我相信是凑效的。

  而对于方法二,我测试了高清中兴、高清大亚4904机顶盒,发现是可行的,验证了我的想法,但是我没有测原来就可以正常移动焦点的高清机顶盒,是否会因为这个方法出现了不正常的问题。这里有一个现象是,在对div设置了tabIndex属性后,在机顶盒上,div周围会出现焦点框,虽然这是个正常的现象,但毕竟不够美观,当然也有办法去掉这个焦点框,这是后话,不做讨论。

说到这个焦点框,顺便一提,获得焦点后,元素有一个虚线框,总有人挖空心思把它去掉。其实这无疑是对页面易用性的践踏,我们还要考虑一下某些特殊人群的需要,如不用鼠标的高手,鼠标坏了的可怜人或是视力有缺陷的人群。有文章介绍,去掉虚线框在美国是违法的,这是对视力障碍者的一种歧视!从这里我们可以看出美国对人权的尊重,这是一个佐证,也是出于用户体验和人性化的考虑,毕竟你的产品就是为人所用,为人服务的。不过话说会来,我们是讨论在机顶盒上的表现,就最好去掉这焦点框,但美国人的态度是值得学习的。

  最后,当页面焦点采用a标签来接受时,因为a标签支持遥控器方向键移动焦点,与Tab键作用类似(比如全部用a标签来接受焦点的标清页面),小窗口播放视频不会出现无法移动焦点的问题。这也证明了上面的结论。

  这里遗留了一个问题,就是当将用于播放视频的iframe设置tabIndex=”-1”时,页面焦点是不是就无法移动了呢?时间关系,未做测试。

  匆匆成文,且未有客观分析和验证,有些观点难免偏颇,欢迎批评指正。

IPTV小窗口播放视频 页面焦点无法移动的解决方法的更多相关文章

  1. iOS设置竖屏,播放视频可以任性旋转的解决方法,亲测可用

    之前在网上找了很多方法,都是强制横屏,但是如果设备关闭旋转锁定,强制横屏后把设备竖立起来,播放器也会跟着竖过来,但是就回不去了.现在项目要求让app默认都是竖屏,只有在全屏播放的时候可以自由旋转,于是 ...

  2. h5页面滑动卡顿解决方法

    解决方式: 给滚动的元素加样式:-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling(允许独立的滚动区域和触摸回弹) 如果值为au ...

  3. &#65279导致页面顶部空白一行解决方法 【】

    2016年11月7日10:57:10 模板文件生成html文件之后会在body开头处加入一个可见的控制符&#65279,导致页面头部会出现一个空白行.原因是页面的编码是UTF-8 + BOM. ...

  4. &#65279导致页面顶部空白一行解决方法

    模板文件生成html文件之后会在body开头处加入一个可见的控制符&#65279,导致页面头部会出现一个空白行.原因是页面的编码是UTF-8 + BOM. 这种编码方式一般会在windows操 ...

  5. WordPress前台后台页面打开慢的解决方法

    写个人网站用WordPress程序是一个不错的选择,但是目前安装之后速度很慢,后台配置页面半天打不开,在网上查了一下原来是Google被墙导致,WordPress默认模板会加载谷歌的open-sans ...

  6. Tomcat启动后,访问页面报404错误解决方法

    Tomcat正常启动后,出现如下情况 提供一个参考解决方法: 1.双击servers 2.把Server Locations设置为User Tomcat installation 保存后再次访问页面就 ...

  7. macOS Sierra 触控板无法三指拖移窗口、三指选中文字的解决方法

    问题:升级macOS Sierra新系统后,发现触摸板无法进行三指拖移窗口.三指选定文字的操作.在“系统偏好设置”——“触控板”内无法进行设置. 解决:“系统偏好设置”——“辅助功能”——“鼠标与触控 ...

  8. 微信小程序访问豆瓣api报403错误解决方法

    通过豆瓣API可以获取很多电影.书籍的数据信息,今天在调用豆瓣正在上映电影接口的时候报403错误,原因是豆瓣设置了小程序的访问权限.如下: 解决方法是使用代理,将豆瓣API地址换成 https://d ...

  9. 微信小程序播放视频发送弹幕效果

    首先.先来看一下效果图 然后.再看一下官方文档API对video的说明 相关属性解析: danmu-list:弹幕列表 enable-danmu:是否显示弹幕 danmu-btn:弹幕按钮 contr ...

随机推荐

  1. python 3.5 之 单双三引号

    1. 单引号和双引号用法都是一样的,但是如果字符串里有相同的字符时要使用\进行转义 举例:1) print 'hello'2) print "hello"1和2,结果都是hello ...

  2. stack 集合栈计算机 (摘)

    有一个专门为了集合运算而设计的“集合栈”计算机.该机器有一个初始为空的栈,并且支持以下操作:PUSH:空集“{}”入栈DUP:把当前栈顶元素复制一份后再入栈UNION:出栈两个集合,然后把两者的并集入 ...

  3. Direct2D DirectWrite绘制文字

    绘制文本使用DirectWrite: 为了简化 DirectWrite 的使用,RenderTarget有3个方法可以直接绘制文本: DrawText,用于简单绘制,支持Unicode. DrawTe ...

  4. Router和History (路由控制)-backbone

    Router和History (路由控制) Backbone.Router担任了一部分Controller(控制器)的工作,它一般运行在单页应用中,能将特定的URL或锚点规则绑定到一个指定的方法(后文 ...

  5. AngularJS 之Services讲解

    Angular带来了很多类型的services.每个都会它自己不同的使用场景.我们将在本节来阐述. 首先我们必须记在心里的是所有的services都是singleton(单例)的,这也是我们所希望得到 ...

  6. ListView的小知识

    1.设置项目分割功能 android:divider="@android:color/blue" android:dividerHeight="10dp" &l ...

  7. tp其他功能

    数据缓存 在ThinkPHP中进行缓存操作,一般情况下并不需要直接操作缓存类,因为系统内置对缓存操作进行了封装,3.1版本推荐的数据缓存方法是cache方法,基本的用法是:(3.1.2版本cache方 ...

  8. Lotto--poj2245

    Lotto Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6605   Accepted: 4185 Description ...

  9. 配置阿里云作为yum 源

    第一步:下载aliyum 的yum源配置文件. http://mirrors.aliyun.com/repo/ 第二步:把下载到的repo文件复制到/etc/yum.repo.d/目录下. ----- ...

  10. SQL Server dbcc shrinkfile 不起作用

    方法 1.重建聚集索引. 方法 2.重建堆表. ---------------------------------------------------------------------------- ...