Greasy Fork

Greasy Fork is available in English.

字母导航

提供网页元素的字母导航

当前为 2018-11-04 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴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
// @description  提供网页元素的字母导航
// @author       Veg
// @include    http://*/*
// @include    https://*/*
// @grant        GM_xmlhttpRequest
// ==/UserScript==

//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.playbackRate = 1.4;
            audio.play();
        }
    }
}

let fEight = true;
let element = [];
function switchCtrl(k) {
    if (k.keyCode == 119) {
        if (fEight == true) {
            fEight = false;
            navigationTTS('关闭字母导航');
        }
        else {
            fEight = true;
            navigationTTS('开启字母导航');
        }
    }
    if (fEight == true)
        if (k.keyCode !== 66 &&
            k.keyCode !== 67 &&
            k.keyCode !== 69 &&
            k.keyCode !== 75 &&
            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
//keyup
    switchCtrl(k);
}, null);
//获取数组下标
function getArraySubscript(arrays, obj) {
    var i = arrays.length;
    while (i--) {
        if (arrays[i] === obj) {
            return i;
        }
    }
    return false;
}

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.hasAttribute('disabled') &&
                t.getAttribute('role') !== 'button' &&
                t.getAttribute('aria-hidden') !== 'true')
                if (t.tabIndex >= 0 || t.hasAttribute && t.hasAttribute('tabindex') && t.getAttribute('tabindex') == '-1') {
                    if (t.offsetParent !== null) {
                        var targetSubscript = getArraySubscript(element, t);
                        linkSubscript.push(targetSubscript);
                        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 (!t.hasAttribute('disabled') &&
                t.getAttribute('aria-hidden') !== 'true')
                if (t.tabIndex >= 0 || t.hasAttribute && t.hasAttribute('tabindex') && t.getAttribute('tabindex') == '-1') {
                    if (t.offsetParent !== null) {
                        //var style = window.getComputedStyle(t);
                        //if (style.width !== 0 && style.height !== 0 && style.opacity !== 0 && style.display !== 'none' && style.visibility !== 'hidden')
                        var targetSubscript = getArraySubscript(element, t);
                        buttonSubscript.push(targetSubscript);
                        return t;
                    }
                }
        }
    });
    var button = buttons.filter(function (n) { return n; })
    //复选框导航
    let checkSubscript = [];
    var checkbox = element.map(function (t) {
        if (t.tagName == 'INPUT' && t.getAttribute('type') == 'checkbox' ||
            t.hasAttribute && t.hasAttribute('role') && t.getAttribute('role') == 'checkbox') {
            if (!t.hasAttribute('disabled') &&
                t.getAttribute('aria-hidden') !== 'true')
                if (t.tabIndex >= 0 || t.hasAttribute && t.hasAttribute('tabindex') && t.getAttribute('tabindex') == '-1') {
                    if (t.offsetParent !== null) {
                        var targetSubscript = getArraySubscript(element, t);
                        checkSubscript.push(targetSubscript);
                        return t;
                    }
                }
        }
    });
    var check = checkbox.filter(function (n) { return n; })
    //文本框导航
    let textSubscript = [];
    var textbox = element.map(function (t) {
        if (t.tagName == 'INPUT' && t.getAttribute('type') == 'text' ||
t.tagName == 'INPUT' && t.getAttribute('type') == null || 
            t.tagName == 'TEXTAREA' ||
            t.hasAttribute && t.hasAttribute('role') && t.getAttribute('role') == 'textbox') {
            if (!t.hasAttribute('disabled') &&
                t.getAttribute('aria-hidden') !== 'true')
                if (t.tabIndex >= 0 || t.hasAttribute && t.hasAttribute('tabindex') && t.getAttribute('tabindex') == '-1') {
                    if (t.offsetParent !== null) {
                        var targetSubscript = getArraySubscript(element, t);
                        textSubscript.push(targetSubscript);
                        return t;
                    }
                }
        }
    });
    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 (!t.hasAttribute('disabled') &&
                t.getAttribute('aria-hidden') !== 'true')
                if (t.tabIndex >= 0 || t.hasAttribute && t.hasAttribute('tabindex') && t.getAttribute('tabindex') == '-1') {
                    if (t.offsetParent !== null) {
                        var targetSubscript = getArraySubscript(element, t);
                        comboSubscript.push(targetSubscript);
                        return t;
                    }
                }
        }
    });
    var combo = combobox.filter(function (n) { return n; })

    element.length = 0;
    //反向切换
    if (k.shiftKey && k.keyCode == 75) {
        for (var i = 0, l = link.length || linkSubscript.length; i < l; i++) {
            if (nFES > linkSubscript[l - 1] || nFES <= linkSubscript[0]) {
                link[l - 1].focus();
                break;
            }
            else {
                if (nFES <= linkSubscript[i]) {
                    var xv = getArraySubscript(link, link[i]);
                    link[xv - 1].focus();
                    reverseAccident(link, xv);
                    break;
                }
            }
        }
    }

    if (k.shiftKey && k.keyCode == 66) {
        for (var i = 0, l = button.length || buttonSubscript.length; i < l; i++) {
            if (nFES > buttonSubscript[l - 1] || nFES <= buttonSubscript[0]) {
                button[l - 1].focus();
                break;
            }
            else {
                if (nFES <= buttonSubscript[i]) {
                    var xv = getArraySubscript(button, button[i]);
                    button[xv - 1].focus();
                    reverseAccident(button, xv);
                    break;
                }
            }
        }
    }
    if (k.shiftKey && k.keyCode == 88) {
        for (var i = 0, l = check.length || checkSubscript.length; i < l; i++) {
            if (nFES > checkSubscript[l - 1] || nFES <= checkSubscript[0]) {
                check[l - 1].focus();
                break;
            }
            else {
                if (nFES <= checkSubscript[i]) {
                    var xv = getArraySubscript(check, check[i]);
                    check[xv - 1].focus();
                    reverseAccident(check, xv);
                    break;
                }
            }
        }
    }

    if (k.shiftKey && k.keyCode == 69) {
        for (var i = 0, l = text.length || textSubscript.length; i < l; i++) {
            if (nFES > textSubscript[l - 1] || nFES <= textSubscript[0]) {
                text[l - 1].focus();
                break;
            }
            else {
                if (nFES <= textSubscript[i]) {
                    var xv = getArraySubscript(text, text[i]);
                    text[xv - 1].focus();
                    reverseAccident(text, xv);
                    break;
                }
            }
        }
    }

    if (k.shiftKey && k.keyCode == 67) {
        for (var i = 0, l = combo.length || comboSubscript.length; i < l; i++) {
            if (nFES > comboSubscript[l - 1] || nFES <= comboSubscript[0]) {
                combo[l - 1].focus();
                break;
            }
            else {
                if (nFES <= comboSubscript[i]) {
                    var xv = getArraySubscript(combo, combo[i]);
                    combo[xv - 1].focus();
                    reverseAccident(combo, xv);
                    break;
                }
            }
        }
    }

    //正向切换
    if (k.altKey || k.ctrlKey || k.shiftKey) return false;
    if (k.keyCode == 75) {
        for (var i = 0, l = link.length || linkSubscript.length; i < l; i++) {
            if (nFES < linkSubscript[i]) {
                var xv = getArraySubscript(link, link[i]);
                link[xv].focus();
                positiveAccident(link, xv);
                break;
            }
            else {
                if (nFES < linkSubscript[0] || nFES >= linkSubscript[l - 1]) {
                    link[0].focus();
                    break;
                }
            }
        }
    }

    if (k.keyCode == 66) {
        for (var i = 0, l = button.length || buttonSubscript.length; i < l; i++) {
            if (nFES < buttonSubscript[i]) {
                var xv = getArraySubscript(button, button[i]);
                button[xv].focus();
                positiveAccident(button, xv);
                break;
            }
            else {
                if (nFES < buttonSubscript[0] || nFES >= buttonSubscript[l - 1]) {
                    button[0].focus();
                    break;
                }
            }
        }
    }

    if (k.keyCode == 88) {
        for (var i = 0, l = check.length || checkSubscript.length; i < l; i++) {
            if (nFES < checkSubscript[i]) {
                var xv = getArraySubscript(check, check[i]);
                check[xv].focus();
                positiveAccident(check, xv);
                break;
            }
            else {
                if (nFES < checkSubscript[0] || nFES >= checkSubscript[l - 1]) {
                    check[0].focus();
                    break;
                }
            }
        }
    }


    if (k.keyCode == 69) {
        for (var i = 0, l = text.length || textSubscript.length; i < l; i++) {
            if (nFES < textSubscript[i]) {
                var xv = getArraySubscript(text, text[i]);
                text[xv].focus();
                positiveAccident(text, xv);
                break;
            }
            else {
                if (nFES < textSubscript[0] || nFES >= textSubscript[l - 1]) {
                    text[0].focus();
                    break;
                }
            }
        }
    }

    if (k.keyCode == 67) {
        for (var i = 0, l = combo.length || comboSubscript.length; i < l; i++) {
            if (nFES < comboSubscript[i]) {
                var xv = getArraySubscript(combo, combo[i]);
                combo[xv].focus();
                positiveAccident(combo, xv);
                break;
            }
            else {
                if (nFES < comboSubscript[0] || nFES >= comboSubscript[l - 1]) {
                    combo[0].focus();
                    break;
                }
            }
        }
    }

}

(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;

            setTimeout(function () {
                //navigationTTS('字母导航准备好了');
            }, 50);

        }
    });
})();

function reverseAccident(e, xv) {
    var ev = e[xv - 1].innerText;
    while (ev !== document.activeElement.innerText) {
        xv--
        e[xv - 1].focus();
        ev = e[xv - 1].innerText;
    }
}
function positiveAccident(e, xv) {
    var ev = e[xv].innerText;
    while (ev !== document.activeElement.innerText) {
        xv++
        e[xv].focus();
        ev = e[xv].innerText;
    }
}
var audio = new Audio("https://veg.ink/music/sound.mp3");
audio.volume = 0.15;
audio.play();