改了人家一个 addon 的脚本,增加了隐藏/显示元素的功能,方便喜欢“眼不见为净”的人

2015-01-01 20:04:06 +08:00
 imn1

不算100%创造,不知放什么节点

https://addons.mozilla.org/en-US/firefox/addon/xpathprototyping
https://github.com/polkovnikov-ph/xpath-prototyping
改了上面这个script,放入油猴可用
可以简单实现 xpath 选择并隐藏元素,css select 的支持就懒得研究了
例如可以在本页输入 //img 试试
兼容性不好,某些有后台ajax刷新的网页会出现跳转或关闭
无版权、无著作权,一切权利归原作者,改了@name只是为了不冲突,谁要修改自用自便,转发请参考原作者的声明

另外有兴趣的人可以装这个玩
https://addons.mozilla.org/en-US/firefox/addon/element-locator-for-webdriv
提取网页元素的xpath,支持多种语言的格式

油猴脚本 Javascript

// ==UserScript==
// @name        xpath-hide-element
// @namespace   wtf-is-namespace
// @description HTML data mining
// @version     0.1
// @grant       none
// ==/UserScript==

var FIREBUG_MODE = true;

function createXPathFromElement(elm) {
    for (segs = []; elm && elm.nodeType == 1; elm = elm.parentNode) {
        var name = elm.localName.toLowerCase();
        if (name == 'html') { segs.unshift(name); break; }
        var i;
        for (i = 1, sib = elm.previousSibling; sib; sib = sib.previousSibling)
            if (sib.localName == elm.localName)
                ++i;
        if (FIREBUG_MODE) {
            if (i > 1)
                name += '[' + i + ']';
        } else {
            if (elm.hasAttribute('id') && elm.getAttribute('id') != "") {
                name += '[@id="' + elm.getAttribute('id') + '"]';
            } else {
                name += '[' + i + ']';
                if (elm.hasAttribute('class') && elm.getAttribute('class') != "")
                    name += '[@class="' + elm.getAttribute('class') + '"]';
            }
        }
        segs.unshift(name);
    }
    return segs.length ? '/' + segs.join('/') : null;
}

function lookupElementByXPath(path) {
    var evaluator = new XPathEvaluator();
    var result = evaluator.evaluate(path, document.documentElement, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
    return result.singleNodeValue;
}

function lookupElementsByXPath(x) {
    var result = document.evaluate(x, document.documentElement, null, 5, null);
    var res = [], next;
    while (next = result.iterateNext())
        res.push(next);
    return res;
}

var reverseStyle = [];
function unStyle() {
    for (var i = 0; i < reverseStyle.length; ++i)
        reverseStyle[i][0].style.cssText = reverseStyle[i][1];
}

function drawFromPath(path) {
    var list = lookupElementsByXPath(path);
    unStyle();
    for (var i = 0; i < list.length; ++i) {
        reverseStyle.push([list[i], list[i].style.cssText]);
        if (list[i].tagName.toLowerCase() == "img") {
            list[i].style.border = '3px solid yellow';
        } else {
            list[i].style.background = '#FFFFA0';
        }
    }
}

function hideFromPath(path) {
    var list = lookupElementsByXPath(path);
    unStyle();
    for (var i = 0; i < list.length; ++i) {
        reverseStyle.push([list[i], list[i].style.cssText]);
        list[i].style.display = 'none';
    }
}

function showFromPath(path) {
    var list = lookupElementsByXPath(path);
    unStyle();
    for (var i = 0; i < list.length; ++i) {
        reverseStyle.push([list[i], list[i].style.cssText]);
        list[i].style.display = 'block';
    }
}

document.documentElement.addEventListener("click", function(event) {
    if (!event.altKey) return;
    if (event === undefined) event = window.event;
    var target = 'target' in event ? event.target : event.srcElement;
    var path = createXPathFromElement(target);
    document.getElementById("xpath").value = path;
    drawFromPath(path);
    return false;
});

var Base64 = {
    // private property
    _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
    // public method for encoding
    encode : function (input) {
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;
        input = Base64._utf8_encode(input);
        while (i < input.length) {
            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);
            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;
            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }
            output = output +
            Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
            Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4);
        }
        return output;
    },

    // public method for decoding
    decode : function (input) {
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;
        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
        while (i < input.length) {
            enc1 = Base64._keyStr.indexOf(input.charAt(i++));
            enc2 = Base64._keyStr.indexOf(input.charAt(i++));
            enc3 = Base64._keyStr.indexOf(input.charAt(i++));
            enc4 = Base64._keyStr.indexOf(input.charAt(i++));
            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;
            output = output + String.fromCharCode(chr1);
            if (enc3 != 64) {
                output = output + String.fromCharCode(chr2);
            }
            if (enc4 != 64) {
                output = output + String.fromCharCode(chr3);
            }
        }
        output = Base64._utf8_decode(output);
        return output;
    },

    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";
        for (var n = 0; n < string.length; n++) {
            var c = string.charCodeAt(n);
            if (c < 128) {
                utftext += String.fromCharCode(c);
            } else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            } else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }
        }
        return utftext;
    },

    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = 0, c1 = 0, c2 = 0;

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);

            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c1 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
                i += 2;
            }
            else {
                c1 = utftext.charCodeAt(i+1);
                c2 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
                i += 3;
            }

        }
        return string;
    }
}

window.addEventListener("load", function () {
    body = document.getElementsByTagName("body")[0];
    var space = document.createElement('div');
    space.style.height = "34px";
    space.style.clear = "both";
    body.appendChild(space);
    div = document.createElement("div");
    div.innerHTML = "\
    <div id=\"xpather\" style=\"position: fixed; left: 0px; top: 100%; margin-top: -34px; width: 100%; height: 34px; background: white; z-index: 32768;\">\
        <table style=\"border: 0px; padding: 0px; border-collapse:collapse; width: 100%; height: 34px; background-repeat: repeat-x;background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAiCAIAAAARTyRGAAAABGdBTUEAALGPC/xhBQAAAINJREFUGFcFwdkSgQAAQNH7A5492k1qKqV90aIINZliGMswvPsFv+4cOt0B9++P/Pgha9+kzYvk8CSuH0TVjbC8Euwv+NszXnHCXbc4eYO1OmCmNUZcsYhKtOWOeVCg+hsUN0d2MiQ7RTQTZkaEoIdMtYCJ6jFWXEayzVCy6IsGPUH/A1YQGPVUbzmcAAAAAElFTkSuQmCC)\">\
            <tr>\
                <td style=\"vertical-align: middle; padding:0px; width: 21px; background-repeat: no-repeat; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAiCAIAAAA/CgXUAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAbNJREFUSEul1LtOwlAcx/HjAzgJGoOIchMvUEBuhSLQUigUyq0ICFjFaNSor2Cc3XV2d3fXWWfdfRB/BgYCDPSUfJaT/L9tOW3OwuLKJjHy693dG0FE9cwIkm0MjCB8/WRIaAyKR1dK/0bRbudHMlUN+Nqp3Lly7IXNa/alVdv8SLrSB6l1gXh53bXmZKxu//xIqtwFuXNpttitbsbmCepCkqUjKHYu8cy6yuEw4eQ2FNoXlH2i0AKpdU7Zx6Um5A/PKHs214CcOqDsY2IdxMYpZR8RqiDUtOn++eV1/I1MLEf7H+YrIFSPp/vP79+39y9Z1YajE8tRH0qXgVd6M++PBh4enzCN+48vR/1+qgQZpTvz/ze16/fPH2Svbx8IJpb/30/goAipcoey93MSHMhtyudnEnlIFluU++djReCkJuX788aykMirlN/PbpSHeK5O2e+EM8CKNcp+O5SCWLZK2XuCSYjyCmXvDnAQSpdMls31Lb/eI4y4mDgw8ZzV5cX5q/cSxOljwe3nAlwBlzBZNuY//DFJHN7okMvH+mJCMCnpQuy7ESPIxk7ICKJ3wyfm/wD+N9ogH8OeTAAAAABJRU5ErkJggg==);\"></td>\
                <td style=\"padding:0px; padding-left:3px; vertical-align: middle; background-repeat: repeat-x; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAiCAIAAAARTyRGAAAABGdBTUEAALGPC/xhBQAAADlJREFUGFdj4BVXZIjJq2dwDUlmcAlOYvCLz2UQlpRnkFUzYJDXMKIJBplvZOvBoKRtxqCgZQKyAwBCnRI+IrS80gAAAABJRU5ErkJggg==);\" >\
                    <div style=\"display: inline-block; width: 100%;\">\
                        <input id=\"xpath\" type=\"text\" style=\"margin: 0px !important; padding: 0px !important; padding-top: 1px; border: none; width: 100% !important; height: 20px !important; background: #272727 !important; color: white !important; font-family: \'Lucida Console\', Verdana, Tahoma, monospace !important;\" />\
                    </div>\
                </td>\
                <td style=\"padding:0px; width: 6px; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAiCAIAAAACmGSyAAAABGdBTUEAALGPC/xhBQAAAUhJREFUOE910mtPgmAUwPGnD9Cr1NYU75hpAhpeEBBFQARFVMx7pq6mW+sr9NXD1XbO3Dj7vftvZzvbubm9T5Gg2Xz/BCG6dwxCtOkhCHG2X9bqrHl7dfJ+hYRj6cxz1V6e1fG+4+4wQmWZCJX1c3/x2R5tMZLIV2I0G46m7dVJGa6xS/PdPSSs5UkerDBo/k7JXmDQzPmH2J9j0Hqvx6Y5w6AZ3kEwphg0fbpv6BMMWne8q3VdDDX3raqOMGiqs+HbQwxax1m/KAMMmjJcllsWBq1lLzjJxKDJ1pwVexg0yZwxgo5BE3teqaFh0JrGpFhXMWiCPi5UOxi0huY+8QoGra46+YqMXRqV40LRFN8e5MoSRuKPXCROU3SJbRo028RIKJr0Q1nq5zgxywgYqcgm0+jSrJAp1a+QdLEWhCQLfJD/G/4++Mov51bLSPWQBGkAAAAASUVORK5CYII=);\"></td>\
                <td style=\"padding-left: 10px; padding-right: 10px; width: 130px; vertical-align: middle;\">\
                    <a id=\"hideAll\" href=\"#\" style=\"font-size: 10pt; text-decoration: none; color: #D0D0D0;\" onmouseout=\"this.style.cssText='font-size: 10pt; text-decoration: none; color: #D0D0D0;';\" onmouseover=\"this.style.cssText='font-size: 10pt; text-decoration: none; color: #5080FF; text-shadow: 0 0 3px #5080FF;';\"> HIDE </a>\
                    <a id=\"showAll\" href=\"#\" style=\"font-size: 10pt; text-decoration: none; color: #D0D0D0;\" onmouseout=\"this.style.cssText='font-size: 10pt; text-decoration: none; color: #D0D0D0;';\" onmouseover=\"this.style.cssText='font-size: 10pt; text-decoration: none; color: #5080FF; text-shadow: 0 0 3px #5080FF;';\"> SHOW </a>\
                    <a id=\"closethis\" href=\"#\" style=\"font-size: 10pt; text-decoration: none; color: #D0D0D0;\" onmouseout=\"this.style.cssText='font-size: 10pt; text-decoration: none; color: #D0D0D0;';\" onmouseover=\"this.style.cssText='font-size: 10pt; text-decoration: none; color: #5080FF; text-shadow: 0 0 3px #5080FF;';\"> CLOSE </a>\
                </td>\
            </tr>\
        </table>\
    </div>";
    body.appendChild(div);
    document.getElementById("xpath").addEventListener("keyup", function (event) {
        var xpath = document.getElementById("xpath").value;
        if (xpath == "") {
            unStyle();
        } else {
            drawFromPath(xpath);
        }
    });
    document.getElementById("hideAll").addEventListener("click", function (event) {
        var xpath = document.getElementById("xpath").value;
        if (xpath == "") {
            unStyle();
        } else {
            hideFromPath(xpath);
        }
    });
    document.getElementById("showAll").addEventListener("click", function (event) {
        var xpath = document.getElementById("xpath").value;
        if (xpath == "") {
            unStyle();
        } else {
            showFromPath(xpath);
        }
    });
    document.getElementById("closethis").addEventListener("click", function (event) {
        document.getElementById("xpather").style.display="none";
        return false;
    });
});
3608 次点击
所在节点    分享创造
8 条回复
imn1
2015-01-01 20:28:36 +08:00
居然是4小时前……
怪不得不上首页~
@Livid
ltm
2015-01-01 20:57:22 +08:00
mozilla addon 都封了。。。
imn1
2015-01-01 21:06:53 +08:00
@ltm
无言以对……
wenketel
2015-01-01 22:06:14 +08:00
@ltm 只是因为EdgeCast被牵连了而已
aaaa007cn
2015-01-01 22:09:41 +08:00
这是干什么的……
原版好像也只是查看 xpath 的
要隐藏元素还少个用来持久化规则的组件
或者只是为了配合 rip / yarip 来用的?
css 选择符直接用 document.querySelector 就好了嘛
imn1
2015-01-01 22:32:41 +08:00
@aaaa007cn
这个不是持久化的,那是adblock之类做的事
这个值是临时清理一下网页不想看的元素,加了display=none / block 而已
例如只想看文章,而页面图片太多,输入个//img 点 hide 就“眼不见为净”了,实际图片还是加载了的,类似还能清理其他元素,需要懂点 xpath

我还有用一个别人写的另外的脚本,可以鼠标点哪个就隐藏/去掉哪个的,但有时太多逐个点就嫌麻烦
例如我查某样东西,结果是含有ABCD四类,我不关心A类的,而查找条件可能没这个类别选择,就可以用 xpath 把含有A类字样的都隐藏了
例如查太平洋的笔记本,它把停产无报价的都列出来,有时还好几页都是

需求场合可能不是太多,但有时还是有点用的
本来做成addon开关按钮好点
只是改了人家的东西自用,没做成产品,也不大算维护,只是分享一下,有需要就拿去自己改吧
有人想造成成品就从原作者那里 fork 好了
aaaa007cn
2015-01-02 00:18:42 +08:00
原来如此
嗯……
yarip 没有临时规则组
rip 年代久远记不清啥样了

话说你那个要隐藏含有 A 类字样的例子就需要规则的持久化啊……
imn1
2015-01-02 00:50:21 +08:00
@aaaa007cn
只是方便某次使用,说不准可能下次查询就需要看 A类
如果长久不需要就该用 privoxy 或 adblock 之类了,我在 privoxy 就设了豆瓣过滤所有招聘帖子

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/158484

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX