Greasy Fork

Greasy Fork is available in English.

字母导航

提供网页元素的字母导航

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         字母导航
// @namespace    https://www.zhihu.com/people/yin-xiao-bo-11
// @version      0.1.5
// @description  提供网页元素的字母导航
// @author       Veg
// @include    http://*/*
// @include    https://*/*
// @grant        GM_xmlhttpRequest
// ==/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 element = [];
let nFES;
let nState = localStorage.getItem('navigationState');
function textNavigation(k) {
//文本框导航
let textSubscript = [];
var text = textFunction(textSubscript);
//组合框导航
let comboSubscript = [];
var combo = formimg('SELECT', 'combobox', comboSubscript);

element.length = 0;

if (ifTrue(document.activeElement) == true) return false;

if (k.shiftKey && k.keyCode == 67) {
reverseJump(combo, comboSubscript);
}
if (k.shiftKey && k.keyCode == 69) {
reverseJump(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 (nState == 'open' || nState == null) {
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 (nState === 'open' || nState == null) {
localStorage.setItem('navigationState', 'close');
nState = localStorage.getItem('navigationState');
navigationTTS('关闭字母导航');
}
else {
localStorage.setItem('navigationState', 'open');
nState = localStorage.getItem('navigationState');
navigationTTS('开启字母导航');
}
}
if (nState == 'open' || nState == null) {
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 !== 67 &&
k.keyCode !== 68 &&
k.keyCode !== 70 &&
k.keyCode !== 71 &&
k.keyCode !== 72 &&
k.keyCode !== 75 &&
k.keyCode !== 76 &&
k.keyCode !== 82 &&
k.keyCode !== 84 &&
k.keyCode !== 87 &&
k.keyCode !== 88 &&
k.keyCode !== 119 &&
k.keyCode !== 222) {
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);
//setNavigation(k);
}, null);

function lnavigation(k) {
//按钮导航
let buttonSubscript = [];
var button = element.filter(function (t) {
if (t.tagName == 'BUTTON' ||
t.hasAttribute && t.hasAttribute('role') && t.getAttribute('role') == 'button' ||
(t.type == 'file' || t.type == 'button' || t.type == 'submit') && t.tagName == 'INPUT') {
if (abilityDetection(t) == true) {
buttonSubscript.push(getArraySubscript(element, t));
return t;
}
}
});

//界标导航
let landmarkSubscript = [];
var landmark = element.filter(function (t) {
var role = t.getAttribute('role');
if (role == 'banner' || role == 'navigation' || role == 'search' || role == 'main' || role == 'complementary' || role == 'form' || role == 'application' || role == 'contentinfo') {
if (abilityDetection2(t) == true) {
if (!t.hasAttribute('tabindex')) {
t.setAttribute('tabindex', '-1');
if (role == 'banner') {
t.setAttribute('aria-label', '横幅区');
}
if (role == 'navigation') {
t.setAttribute('aria-label', '导航区');
}
if (role == 'search') {
t.setAttribute('aria-label', '搜索区');
}
if (role == 'main') {
t.setAttribute('aria-label', '主内容区');
}
if (role == 'complementary') {
t.setAttribute('aria-label', '补充内容区');
}
if (role == 'form') {
t.setAttribute('aria-label', '表单区');
}
if (role == 'application') {
t.setAttribute('aria-label', '应用程序区');
}
if (role == 'contentinfo') {
t.setAttribute('aria-label', '隐私版权区');
}
}
landmarkSubscript.push(getArraySubscript(element, t));
return t;
}
}
});

//表单导航
let formSubscript = [];
var form = formimg('FORM', 'form', formSubscript);
//图片导航
let imgSubscript = [];
var img = formimg('IMG', 'image', imgSubscript);
//链接导航
let linkSubscript = [];
var link = element.filter(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;
}
}
});
//复选框导航
let checkSubscript = [];
var check = formFunction('INPUT', 'checkbox', checkSubscript);

//单选复选框导航
let radioSubscript = [];
var radio = formFunction('INPUT', 'radio', radioSubscript);

//标题导航
let heaSubscript = [];
var hea = element.filter(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');
t.addEventListener('keydown', function (k) {
if (k.keyCode == 13) {
if (t.querySelector('a') !== null) {
this.querySelector('a').setAttribute('target', 'blank');
this.querySelector('a').click();
}
var host = window.location.host;
if (host === 'www.google.com' || host === 'www.google.com.hk') {
var parent = this.parentNode.parentNode;
var link = parent.querySelector('a');
if (link !== null)
link.setAttribute('target', 'blank');
link.click();
}
}
}, null);
}
heaSubscript.push(getArraySubscript(element, t));
return t;
}
}
});
//一级标题
let hea1Subscript = [];
var hea1 = head('H1', '1', hea1Subscript);
//二级标题
let hea2Subscript = [];
var hea2 = head('H2', '2', hea2Subscript);
//三级标题
let hea3Subscript = [];
var hea3 = head('H3', '3', hea3Subscript);
//四级标题
let hea4Subscript = [];
var hea4 = head('H4', '4', hea4Subscript);
//五级标题
let hea5Subscript = [];
var hea5 = head('H5', '5', hea5Subscript);
//六级标题
let hea6Subscript = [];
var hea6 = head('H6', '6', hea6Subscript);
//列表导航
let ulSubscript = [];
var ul = formimg('UL', 'list', ulSubscript);

//表格导航
let tableSubscript = [];
var table = element.filter(function (t) {
if (t.tagName == 'TABLE') {
if (abilityDetection2(t) == true) {
if (!t.hasAttribute('tabindex')) {
t.setAttribute('tabindex', '-1');
}
tableSubscript.push(getArraySubscript(element, t));
return t;
}
}
});
//组合框和文本框
let combo1Subscript = [];
var combo1 = formimg('SELECT', 'combobox', combo1Subscript);
let text1Subscript = [];
var text1 = textFunction(text1Subscript);

element.length = 0;

if (k.altKey && k.keyCode == 67) {
positiveJump(combo1, combo1Subscript);
}
if (!k.shiftKey) {
if (k.altKey && k.keyCode == 87) {
positiveJump(text1, text1Subscript);
}
}
if (k.shiftKey && k.altKey && k.keyCode == 87) {
reverseJump(text1, text1Subscript);
}
if (ifTrue(document.activeElement) == true) return false;
if (k.ctrlKey || k.altKey) return false;
//反向切换
if (k.shiftKey && k.keyCode == 66) {
reverseJump(button, buttonSubscript);
}
if (k.shiftKey && k.keyCode == 68) {
reverseJump(landmark, landmarkSubscript);
}
if (k.shiftKey && k.keyCode == 70) {
reverseJump(form, formSubscript);
}
if (k.shiftKey && k.keyCode == 71) {
for (var i = 0, l = img.length; i < l; i++) {
img[i].setAttribute('title', '图片' + (i + 1));
}
reverseJump(img, imgSubscript);
}
if (k.shiftKey && k.keyCode == 75) {
reverseJump(link, linkSubscript);
}
if (k.shiftKey && k.keyCode == 76) {
reverseJump(ul, ulSubscript);
}
if (k.shiftKey && k.keyCode == 82) {
reverseJump(radio, radioSubscript);
}
if (k.shiftKey && k.keyCode == 84) {
reverseJump(table, tableSubscript);
tableSupport();
}
if (k.shiftKey && k.keyCode == 88) {
reverseJump(check, checkSubscript);
}
if (k.shiftKey && k.keyCode == 72) {
reverseJump(hea, heaSubscript);
}
if (k.shiftKey && k.keyCode == 49) {
reverseJump(hea1, hea1Subscript);
}
if (k.shiftKey && k.keyCode == 50) {
reverseJump(hea2, hea2Subscript);
}
if (k.shiftKey && k.keyCode == 51) {
reverseJump(hea3, hea3Subscript);
}
if (k.shiftKey && k.keyCode == 52) {
reverseJump(hea4, hea4Subscript);
}
if (k.shiftKey && k.keyCode == 53) {
reverseJump(hea5, hea5Subscript);
}
if (k.shiftKey && k.keyCode == 54) {
reverseJump(hea6, hea6Subscript);
}

//正向切换
if (k.shiftKey) return false;
if (k.keyCode == 66) {
positiveJump(button, buttonSubscript);
}

if (k.keyCode == 68) {
positiveJump(landmark, landmarkSubscript);
}
if (k.keyCode == 70) {
positiveJump(form, formSubscript);
}
if (k.keyCode == 71) {
for (var i = 0, l = img.length; i < l; i++) {
img[i].setAttribute('title', '图片' + (i + 1));
}
positiveJump(img, imgSubscript);
}
if (k.keyCode == 75) {
positiveJump(link, linkSubscript);
}
if (k.keyCode == 76) {
positiveJump(ul, ulSubscript);
}
if (k.keyCode == 82) {
positiveJump(radio, radioSubscript);
}
if (k.keyCode == 84) {
positiveJump(table, tableSubscript);
tableSupport();
}
if (k.keyCode == 88) {
positiveJump(check, checkSubscript);
}

if (k.keyCode == 72) {
positiveJump(hea, heaSubscript);
}
if (k.keyCode == 49) {
positiveJump(hea1, hea1Subscript);
}
if (k.keyCode == 50) {
positiveJump(hea2, hea2Subscript);
}
if (k.keyCode == 51) {
positiveJump(hea3, hea3Subscript);
}
if (k.keyCode == 52) {
positiveJump(hea4, hea4Subscript);
}
if (k.keyCode == 53) {
positiveJump(hea5, hea5Subscript);
}
if (k.keyCode == 54) {
positiveJump(hea6, hea6Subscript);
}
}
//正向导航函数
function positiveJump(a, b) {
for (var i = 0, l = a.length || b.length; i < l; i++) {
if (nFES < b[i]) {
var xv = getArraySubscript(a, a[i]);
a[xv].focus();
while (a[xv].isSameNode(document.activeElement) !== true) {
xv++
a[xv].focus();
}
break;
}
else {
if (nFES < b[0] || nFES >= b[l - 1]) {
a[0].focus();
break;
}
}
}
}
//反向导航函数
function reverseJump(a, b) {
for (var i = 0, l = a.length || b.length; i < l; i++) {
if (nFES > b[l - 1] || nFES <= b[0]) {
a[l - 1].focus();
break;
}
else {
if (nFES <= b[i]) {
var xv = getArraySubscript(a, a[i]);
a[xv - 1].focus();
while (a[xv - 1].isSameNode(document.activeElement) !== true) {
xv--
a[xv - 1].focus();
}
break;
}
}
}
}
//获取数组下标
function getArraySubscript(arrays, obj) {
var i = arrays.length;
while (i--) {
if (arrays[i] === obj) {
return i;
}
}
return false;
}
//分级标题函数
function head(a, b, c) {
var d = element.filter(function (t) {
if (t.tagName == a) {
if (abilityDetection2(t) == true) {
if (t.getAttribute('aria-level') == null) {
t.setAttribute('aria-level', b);
t.setAttribute('title', a);
}
c.push(getArraySubscript(element, t));
return t;
}
}
});
return d;
}
//文本框函数
function textFunction(c) {
var d = element.filter(function (t) {
if (ifTrue(t) == true) {
if (abilityDetection(t) == true) {
c.push(getArraySubscript(element, t));
return t;
}
}
});
return d;
}

//部分表单函数
function formFunction(a, b, c) {
var d = element.filter(function (t) {
if (t.tagName == a && t.getAttribute('type') == b ||
t.hasAttribute && t.hasAttribute('role') && t.getAttribute('role') == b) {
if (abilityDetection(t) == true) {
c.push(getArraySubscript(element, t));
return t;
}
}
});
return d;
}
//表单图片等
function formimg(a, b, c) {
var d = element.filter(function (t) {
if (t.tagName == a ||
t.hasAttribute && t.hasAttribute('role') && t.getAttribute('role') == b) {
if (abilityDetection2(t) == true) {
if (a !== 'SELECT' && b !== 'combobox') {
if (!t.hasAttribute('tabindex')) {
t.setAttribute('tabindex', '-1');
if (a == 'FORM') {
t.setAttribute('aria-label', '表单');
}
}
}
c.push(getArraySubscript(element, t));
return t;
}
}
});
return d;
}
//条件函数
function ifTrue(t) {
if ((t.type == 'text' || t.type == 'password' || t.type == 'email' || t.type == 'number' || t.type == 'search' || t.type == 'tel' || t.type == 'url') && t.tagName == 'INPUT' ||
t.tagName == 'PRE' ||
t.tagName == 'TEXTAREA' ||
t.tagName == 'INPUT' && t.getAttribute('type') == null ||
t.hasAttribute && t.hasAttribute('role') && t.getAttribute('role') == 'textbox')
return true;
}

function abilityDetection(t) {
if ((t.tabIndex >= 0 || t.hasAttribute && t.hasAttribute('tabindex') && t.getAttribute('tabindex') == '-1') &&
!t.hasAttribute('disabled') &&
t.getAttribute('aria-hidden') !== 'true' &&
t.offsetParent !== null)
return true;
}

function abilityDetection2(t) {
if (!t.hasAttribute('disabled') &&
t.getAttribute('aria-hidden') !== 'true' &&
t.offsetParent !== null)
return true;
}
//表格支持
function tableSupport() {
var fes = document.activeElement;
if (fes.tagName == 'TABLE') {
let trs = [];
let tds = [];
fes.addEventListener('keydown', function (k) {
trs.length = 0;
tds.length = 0;
var tr = this.querySelectorAll('tr');
for (var i = 0, l = tr.length; i < l; i++) {
if (!tr[i].hasAttribute('tabindex')) {
tr[i].setAttribute('tabindex', '-1');
}
trs.push(tr[i]);

var td = tr[i].querySelectorAll('th,td');
for (var j = 0, w = td.length; j < w; j++) {
if (!td[j].hasAttribute('tabindex')) {
td[j].setAttribute('tabindex', '-1');
}
tds.push(td[j]);
}
}
var fe = document.activeElement;
if (k.altKey && k.shiftKey && k.keyCode == 33) {
if (fe.tagName == 'TABLE') {
var len = trs.length;
trs[len - 1].focus();
}
else if (fe.tagName == 'TR') {
var xv = getArraySubscript(trs, fe);
trs[xv - 1].focus();
}
else if (fe.tagName !== 'TR') {
if (fe.tagName == 'TD' || fe.tagName == 'TH') {
incrementTR(fe, trs);
}
else {
while (fe.parentNode.tagName !== 'TR') {
fe = fe.parentNode;
var ttr = fe.parentNode;
if (ttr.tagName == 'TR') {
var xv = getArraySubscript(trs, ttr);
trs[xv].focus();
}
}
}
}
}

if (k.altKey && k.shiftKey && k.keyCode == 34) {
if (fe.tagName == 'TABLE') {
trs[0].focus();
}
else if (fe.tagName == 'TR') {
var xv = getArraySubscript(trs, fe);
trs[xv + 1].focus();
}
else if (fe.tagName !== 'TR') {
if (fe.tagName == 'TD' || fe.tagName == 'TH') {
incrementTR(fe, trs);
}
else {
while (fe.parentNode.tagName !== 'TR') {
fe = fe.parentNode;
var ttr = fe.parentNode;
if (ttr.tagName == 'TR') {
var xv = getArraySubscript(trs, ttr);
trs[xv + 1].focus();
}
}
}
}
}
if (k.altKey && k.shiftKey && k.keyCode == 37) {
if (fe.tagName == 'TR') {
var lastTD = fe.querySelectorAll('td,th');
var lastTD = fe.querySelectorAll('td');
for (var i = 0, l = lastTD.length; i < l; i++) {
lastTD[l - 1].focus();
}
}
else if (fe.tagName == 'TD' || fe.tagName == 'TH') {
var xv = getArraySubscript(tds, fe);
tds[xv - 1].focus();
}
}
if (k.altKey && k.shiftKey && k.keyCode == 39) {
if (fe.tagName == 'TR') {
if (fe.querySelector('th') !== null) {
fe.querySelector('th').focus();
}
else {
fe.querySelector('td').focus();
}
}
else if (fe.tagName == 'TD' || fe.tagName == 'TH') {
var xv = getArraySubscript(tds, fe);
tds[xv + 1].focus();
}
}

}, null);
}
}


function incrementTR(fe, trs) {
while (fe.tagName == 'TD' || fe.tagName == 'TH') {
fe = fe.parentNode;
var ttr = fe;
if (ttr.tagName == 'TR') {
var xv = getArraySubscript(trs, ttr);
trs[xv].focus();
}
}
}
/*
let vx = false;
funcion setNavigation(k) {
//alert(timeout);
let timeout;
var ax=function() {
alert('ok');
vx=false;
};
if(k.keyCode == 192) {
vx = true;
timeout = setTimeout(ax,3000);
}
else if(vx == true && k.key=='v') {
alert(timeout);
clearTimeout(timeout);
vx = false;
var video = document.querySelector('video');
if(video!==null) {
video.controls = true;
video.focus();
return false;
}
}
else if(vx == true && k.key=='a') {
clearTimeout(timeout);
vx = false;
var audio = document.querySelector('audio');
if(audio!==null) {
audio.controls = true;
audio.focus();
return false;
}
}
else if(vx == true && k.key=='w') {
clearTimeout(timeout);
vx = false;
var article = document.querySelector('article');
if(article!==null) {
var div=article.querySelector('div');
div.setAttribute('tabindex','0');
div.focus();
return false;
}
}

}
*/