// ==UserScript== // @name 字母导航 // @namespace https://www.zhihu.com/people/yin-xiao-bo-11 // @version 0.1.2 // @description 提供网页元素的字母导航 // @author Veg // @include http://*/* // @include https://*/* // @grant GM_xmlhttpRequest // @downloadURL none // ==/UserScript== "use strict"; let navigationTTSToken; //TTS 函数 function navigationTTS(TTStext) { var zhText = encodeURI(TTStext); var parameter = "&vol=7&per=0&spd=9&pit=7"; var voicebbUrl = "https://tsn.baidu.com/text2audio?lan=zh&ctp=1&cuid=xiaobo&tok=" + navigationTTSToken + "&tex=" + zhText + parameter; var audio = document.querySelector('audio.audio-navigation'); { if (audio !== null) { audio.src = voicebbUrl; audio.volume = 0.6; audio.playbackRate = 1.4; audio.play(); } } } (function () { //插入播放器 var audio = document.createElement('audio'); audio.className = 'audio-navigation'; audio.volume = 0.6; document.body.appendChild(audio); GM_xmlhttpRequest({ method: "GET", headers: { "Accept": "Content-Type:application/json" }, url: "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=DmRzeWmTGgwPuPrFyHPhxLFH&client_secret=iYUz9bmANfuDBhlpacObRCq4qutDHfSe", onload: function (response) { var data = response.responseText; var datas = JSON.parse(data); navigationTTSToken = datas.access_token; } }); })(); let fEight = true; let element = []; let nFES; function textNavigation(k) { //文本框导航 let textSubscript = []; var textbox = textFunction(textSubscript); var text = textbox.filter(function (n) { return n; }) //组合框导航 let comboSubscript = []; var combobox = element.map(function (t) { if (t.tagName == 'SELECT' || t.hasAttribute && t.hasAttribute('role') && t.getAttribute('role') == 'combobox') { if (abilityDetection(t) == true) { comboSubscript.push(getArraySubscript(element, t)); return t; } } }); var combo = combobox.filter(function (n) { return n; }) element.length = 0; var ef = document.activeElement; if (ifTrue(ef) == true) return false; if (k.altKey && k.keyCode == 67) { positiveJump(combo, comboSubscript); } if (k.shiftKey && k.keyCode == 67) { reverseJump(combo, comboSubscript); } if (k.shiftKey && k.keyCode == 69) { reverseJump(text, textSubscript); } if (k.altKey && k.keyCode == 87) { positiveJump(text, textSubscript); } if (k.altKey || k.shiftKey || k.ctrlKey) return false; if (k.keyCode == 67) { positiveJump(combo, comboSubscript); } if (k.keyCode == 69) { positiveJump(text, textSubscript); } } document.body.addEventListener('keyup', function (k) { if (k.keyCode !== 67 && k.keyCode !== 69 && k.keyCode !== 87) { return false; } else { var all = document.all; for (var i = 0, l = all.length; i < l; i++) { if (all[i].nodeType == 1) { element.push(all[i]); } } nFES = getArraySubscript(element, document.activeElement); textNavigation(k); } }, null); function switchCtrl(k) { if (k.keyCode == 119) { if (fEight == true) { fEight = false; navigationTTS('关闭字母导航'); } else { fEight = true; navigationTTS('开启字母导航'); } } if (fEight == true) if (k.keyCode !== 49 && k.keyCode !== 50 && k.keyCode !== 51 && k.keyCode !== 52 && k.keyCode !== 53 && k.keyCode !== 54 && k.keyCode !== 33 && k.keyCode !== 34 && k.keyCode !== 66 && k.keyCode !== 72 && k.keyCode !== 75 && k.keyCode !== 76 && k.keyCode !== 82 && k.keyCode !== 84 && k.keyCode !== 87 && k.keyCode !== 88 && k.keyCode !== 119) { return false; } else { var all = document.all; for (var i = 0, l = all.length; i < l; i++) { if (all[i].nodeType == 1) { element.push(all[i]); } } nFES = getArraySubscript(element, document.activeElement); lnavigation(k); } } document.body.addEventListener('keydown', function (k) { //keydown //keypress //keyup switchCtrl(k); }, null); function lnavigation(k) { //链接导航 let linkSubscript = []; var links = element.map(function (t) { if (t.tagName == 'A' || t.hasAttribute && t.hasAttribute('role') && t.getAttribute('role') == 'link') { if (t.getAttribute('role') !== 'button') if (abilityDetection(t) == true) { linkSubscript.push(getArraySubscript(element, t)); return t; } } }); var link = links.filter(function (n) { return n; }); //按钮导航 let buttonSubscript = []; var buttons = element.map(function (t) { if (t.tagName == 'BUTTON' || t.hasAttribute && t.hasAttribute('role') && t.getAttribute('role') == 'button' || (t.getAttribute('type') == 'button' || t.getAttribute('type') == 'submit') && t.tagName == 'INPUT') { if (abilityDetection(t) == true) { buttonSubscript.push(getArraySubscript(element, t)); return t; } } }); var button = buttons.filter(function (n) { return n; }) //复选框导航 let checkSubscript = []; var checkbox = formFunction('INPUT', 'checkbox', checkSubscript); var check = checkbox.filter(function (n) { return n; }) //单选复选框导航 let radioSubscript = []; var radios = formFunction('INPUT', 'radio', radioSubscript); var radio = radios.filter(function (n) { return n; }) //文本框导航 let textSubscript = []; var textbox = textFunction(textSubscript); var text = textbox.filter(function (n) { return n; }) //标题导航 let heaSubscript = []; var headings = element.map(function (t) { var tag = t.tagName; if (tag == 'H1' || tag == 'H2' || tag == 'H3' || tag == 'H4' || tag == 'H5' || tag == 'H6') { if (abilityDetection2(t) == true) { if (t.getAttribute('tabindex') == null) { t.setAttribute('tabindex', '-1'); t.setAttribute('role', 'heading'); } heaSubscript.push(getArraySubscript(element, t)); return t; } } }); var hea = headings.filter(function (n) { return n; }) //一级标题 let hea1Subscript = []; var heading1 = head('H1', '1', hea1Subscript); var hea1 = heading1.filter(function (n) { return n; }) //二级标题 let hea2Subscript = []; var heading2 = head('H2', '2', hea2Subscript); var hea2 = heading2.filter(function (n) { return n; }) //三级标题 let hea3Subscript = []; var heading3 = head('H3', '3', hea3Subscript); var hea3 = heading3.filter(function (n) { return n; }) //四级标题 let hea4Subscript = []; var heading4 = head('H4', '4', hea4Subscript); var hea4 = heading4.filter(function (n) { return n; }) //五级标题 let hea5Subscript = []; var heading5 = head('H5', '5', hea5Subscript); var hea5 = heading5.filter(function (n) { return n; }) //六级标题 let hea6Subscript = []; var heading6 = head('H6', '6', hea6Subscript); var hea6 = heading6.filter(function (n) { return n; }) //列表导航 let ulSubscript = []; var uls = element.map(function (t) { if (t.tagName == 'UL') { if (abilityDetection2(t) == true) { if (t.getAttribute('tabindex') == null) { t.setAttribute('tabindex', '-1'); t.setAttribute('role', 'list'); } ulSubscript.push(getArraySubscript(element, t)); return t; } } }); var ul = uls.filter(function (n) { return n; }) //表格导航 let tableSubscript = []; //let trs = []; var tables = element.map(function (t) { if (t.tagName == 'TABLE') { if (abilityDetection2(t) == true) { if (!t.hasAttribute('tabindex')) { t.setAttribute('tabindex', '-1'); } //t.setAttribute('role','grid'); //t.setAttribute('role', 'table'); //t.setAttribute('role', 'rowgroup'); //row 行 //rowgroup h 行标头 tableSubscript.push(getArraySubscript(element, t)); return t; } } }); var table = tables.filter(function (n) { return n; }) /* var trs=element.map(function(ts){ if(ts.tagName== 'TR') { //alert('ok'); if(!ts.hasAttribute('tabindex')) { ts.setAttribute('tabindex','0'); } return ts; } }); var tr = trs.filter(function (n) { return n; }) for (var p=0; p