有没有这样的浏览器插件——自动给自定义列表中的词汇加悬浮触发的备注?

简单改了改之前给搜索酱写的小书签

(function() {
    var count = 0,
        text, dv;
    text = prompt("请输入关键词, alt 点击词条下一个, alt 点击词条上一个, r 恢复, c| 用|分隔多个关键词, o 原始文本:", "c|姬无野:小受|尹漱石:大攻");
    if (text == null || text.length == 0) return;
    if(text==="r"){
        [].forEach.call(document.querySelectorAll("mark.searchJumper"),mark=>{
            let newNode = document.createTextNode(mark.innerText);
            mark.parentNode.replaceChild(newNode, mark);
        });
        return;
    }
    if(text.indexOf("o")===0){
        text=[text.substr(1)];
    }else if(text.indexOf("c")===0){
        text=text.substr(1);
        text=text.substr(1).split(text.substr(0,1));
    }else text=[text];
    dv = document.defaultView;
    let marks=[];
    let focusMark;
    function setFocus(ele){
        focusMark.style.border="";
        focusMark=ele;
        focusMark.scrollIntoView({behavior: "smooth", block: "center", inline: "nearest"});
        focusMark.style.border="1px dashed red";
    }
    function searchWithinNode(node, te) {
        let tePair=te.split(":");
        let len=tePair[0].length;
        let pos, skip, spannode, middlebit, middleclone;
        skip = 0;
        if (node.nodeType == 3) {
            pos = node.data.toUpperCase().indexOf(tePair[0]);
            if (pos >= 0) {
                let index=marks.length;
                spannode = document.createElement("mark");
                spannode.className = "searchJumper";
                spannode.title = tePair[1];
                spannode.addEventListener("mousedown", e=>{
                    if (!e.altKey)return;
                    if(e.which === 1 ){
                        if(index!=marks.length-1){
                            setFocus(marks[index+1]);
                        }
                    }else if(e.which === 3){
                        if(index!=0){
                            setFocus(marks[index-1]);
                        }
                    }
                });
                spannode.addEventListener("click", e=>{
                    e.stopPropagation();
                    e.preventDefault();
                    return false;
                });
                middlebit = node.splitText(pos);
                middlebit.splitText(len);
                middleclone = middlebit.cloneNode(true);
                spannode.appendChild(middleclone);
                middlebit.parentNode.replaceChild(spannode, middlebit);
                marks.push(spannode);
                focusMark=spannode;
                ++count;
                skip = 1;
            }
        } else if (node.nodeType == 1 && node.childNodes && node.tagName.toUpperCase() != "SCRIPT" && node.tagName.toUpperCase() != "STYLE" && node.tagName.toUpperCase() != "MARK") {
            for (var child = 0; child < node.childNodes.length; ++child) {
                child = child + searchWithinNode(node.childNodes[child], te, len);
            }
        }
        return skip;
    }
    text.forEach(t=>{searchWithinNode(document.body, t.toUpperCase());})
})();