背景:油管英文视频的字幕按钮每次在听不懂的地方都需要鼠标点击一下让字幕出现,但又不想让字幕一直挂着,所以想实现个类似于空格键控制启停、左右键控制进退的快捷键来控制字幕的出现与否。
F12打开chrome开发者工具,利用拾取器定位按钮所对应的代码,如下图:
点击按钮可以看到中间框的aria-pressed值由false变为true,猜测属性aria-pressed是用于控制字幕是否显示的。在控制台中编写键按下时的回调函数,当delete键按下时改变该属性值,发现并不能触发字幕的显示/关闭。因此,再次尝试,这一次用js模拟按钮点击。和参考链接四一样,直接使用jQuery的click()函数没有任何预期效果。不过,参考链接四给出了问题原因和解决办法。真正点击触发时,事件带的属性更多,模拟点击效果时某些关键属性没有带上,导致模拟点击不能生效。根据参考链接五使用monitorEvents(),查看真实点击时带了哪些属性。如下图是查看效果:
猜测需要给事件带上isTrusted属性,于是修改代码,运行效果达到预期(按一下delete键字幕显示,再按一下字幕消失)。需要输入到Chrome控制台的完整代码如下:
var importJs=document.createElement('script') //在页面新建一个script标签
importJs.setAttribute("type","text/javascript") //给script标签增加type属性
importJs.setAttribute("src", 'https://code.jquery.com/jquery-latest.js') //给script标签增加src属性, url地址为cdn公共库里的
document.getElementsByTagName("head")[0].appendChild(importJs) //把importJs标签添加在页面
function translate(event){
var e = event || window.event || arguments.callee.caller.arguments[0];
if(e.keyCode==46){ // delete键控制字幕出现/消失
var el = $('#movie_player').find('button.ytp-subtitles-button.ytp-button')
console.log(el)
console.log(el[0]);
//el.attr("aria-pressed", "true")
//直接改上面的属性为true或false无法触发事件,虽然真实点击时会改这个属性值
var ev = document.createEvent('HTMLEvents');
ev.isTrusted = true;
ev.initEvent('click', true, false);
el[0].dispatchEvent(ev);
}
};
document.addEventListener('keyup',translate,false);
后续可考虑改进的地方:真实点击所调用的回调函数直接赋值给onkeydown。不知道是看js代码的能力差,还是生产环境js可读性差,另外YouTube源码似乎没有,全是仿的,所以这个改进可能有点难度。
参考链接一(Chrome控制台引用jQuery)
https://blog.csdn.net/aigoChina/article/details/78864647
参考链接二(keyCode与键盘键的对应关系)
https://blog.csdn.net/tspchip/article/details/4836917
参考链接三(JS实现键盘监听(包括组合键))
https://blog.csdn.net/changqing5818/article/details/50037607
参考链接四(js模拟按钮点击)
https://www.cnblogs.com/CyLee/p/7513342.html
参考链接五(Chrome控制台监听事件的api)
https://www.html.cn/doc/chrome-devtools/console/events/
参考链接六(js绑定带参数的事件以及手动触发事件)
https://northc.iteye.com/blog/1245048