Greasy Fork

Greasy Fork is available in English.

Instagram 隐藏图片

调整 Instagram 图片的透明度。

当前为 2020-05-28 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name                Instagram: Hide Image
// @name:zh-TW          Instagram 隱藏圖片
// @name:zh-CN          Instagram 隐藏图片
// @name:ja             Instagram 画像を非表示
// @name:ko             Instagram 이미지 숨기기
// @name:ru             Instagram Скрыть изображение
// @version             1.0.2
// @description         Make Instagram Images Opacity Lower.
// @description:zh-TW   調整 Instagram 圖片的透明度。
// @description:zh-CN   调整 Instagram 图片的透明度。
// @description:ja      Instagram 画像の不透明度を低くします。
// @description:ko      Instagram 이미지 불투명도를 낮추십시오.
// @description:ru      Уменьшите непрозрачность изображений в Instagram.
// @author              Hayao-Gai
// @namespace           https://github.com/HayaoGai
// @icon                https://i.imgur.com/obCmlr9.png
// @match               https://www.instagram.com*
// @grant               GM_getValue
// @grant               GM_setValue
// ==/UserScript==

/* jshint esversion: 6 */

(function() {
    'use strict';

    // icons made by https://www.flaticon.com/authors/pixel-perfect
    const iconOn = `<svg width="35" height="35" viewBox="0 -107 512 512"><path d="m362.667969 298.667969h-213.335938c-82.34375 0-149.332031-67.007813-149.332031-149.335938 0-82.324219 66.988281-149.332031 149.332031-149.332031h213.335938c82.34375 0 149.332031 67.007812 149.332031 149.332031 0 82.328125-66.988281 149.335938-149.332031 149.335938zm-213.335938-266.667969c-64.703125 0-117.332031 52.652344-117.332031 117.332031 0 64.683594 52.628906 117.335938 117.332031 117.335938h213.335938c64.703125 0 117.332031-52.652344 117.332031-117.335938 0-64.679687-52.628906-117.332031-117.332031-117.332031zm0 0"/><path d="m362.667969 234.667969c-47.0625 0-85.335938-38.273438-85.335938-85.335938 0-47.058593 38.273438-85.332031 85.335938-85.332031 47.058593 0 85.332031 38.273438 85.332031 85.332031 0 47.0625-38.273438 85.335938-85.332031 85.335938zm0-138.667969c-29.398438 0-53.335938 23.914062-53.335938 53.332031 0 29.421875 23.9375 53.335938 53.335938 53.335938 29.394531 0 53.332031-23.914063 53.332031-53.335938 0-29.417969-23.9375-53.332031-53.332031-53.332031zm0 0"/></svg>`;
    const iconOff = `<svg width="35" height="35" viewBox="0 -107 512 512"><path d="m362.667969 0h-213.335938c-82.324219 0-149.332031 66.988281-149.332031 149.332031 0 82.347657 67.007812 149.335938 149.332031 149.335938h213.335938c82.324219 0 149.332031-66.988281 149.332031-149.335938 0-82.34375-67.007812-149.332031-149.332031-149.332031zm-213.335938 234.667969c-47.058593 0-85.332031-38.273438-85.332031-85.335938 0-47.058593 38.273438-85.332031 85.332031-85.332031 47.0625 0 85.335938 38.273438 85.335938 85.332031 0 47.0625-38.273438 85.335938-85.335938 85.335938zm0 0"/></svg>`;

    // css
    const textStyle = `
.switch-set {
    margin-left: 20px;
}
.hide-set {
    transition: opacity 0.3s;
}`;

    // target
    const targets = [
        ["img._6q-tv:not(.hide-set)", null],
        ["img.FFVAD:not(.hide-set)", "eLAPa"],
        ["video:not(.hide-set)", "kPFhm"]
    ];

    // update
    let updating = false;

    css();
    init(10);
    locationChange();
    window.addEventListener("scroll", update);

    function init(times) {
        for (let i = 0; i < times; i++) {
            // switch
            setTimeout(switchButton, 500 * i);
            // hide
            for (const target of targets) {
                setTimeout(() => getTarget(target[0], target[1]), 500 * i);
            }
        }
        // show
        showTarget();
    }

    function switchButton() {
        // check exist
        if (!!document.querySelector(".switch-set")) return;
        // panel
        const panel = document.querySelector(".ctQZg");
        if (!panel) return;
        // switch
        const button = document.createElement("button");
        button.className = "dCJp8 afkep switch-set";
        button.innerHTML = getSwitch() ? iconOn : iconOff;
        button.addEventListener("click", onClick);
        panel.appendChild(button);
    }

    function onClick() {
        const afterClick = !getSwitch();
        GM_setValue("switch", afterClick);
        this.innerHTML = afterClick ? iconOn : iconOff;
        init(3);
    }

    function getTarget(target, root) {
        // check switch.
        if (!getSwitch()) return;
        // hide target.
        document.querySelectorAll(target).forEach(t => {
            t.classList.add("hide-set");
            t.style.opacity = 0.1;
            // the hover is at root.
            if (!!root) {
                if (!t.closest(`div.${root}`)) return;
                const div = t.closest(`div.${root}`).lastElementChild;
                div.addEventListener("mouseenter", addListener);
                div.addEventListener("mouseleave", addListener);
                return;
            }
            // no need to get root.
            t.addEventListener("mouseenter", addListener);
            t.addEventListener("mouseleave", addListener);
        });
    }

    function showTarget() {
        // check switch
        if (getSwitch()) return;
        // show
        for (const target of targets) {
            const tag = target[0].split(":")[0];
            const root = target[1];
            document.querySelectorAll(`${tag}.hide-set`).forEach(t => {
                t.classList.remove("hide-set");
                t.style.opacity = 1;
                // the hover is at root.
                if (!!root) {
                    if (!t.closest(`div.${root}`)) return;
                    const div = t.closest(`div.${root}`).lastElementChild;
                    div.removeEventListener("mouseenter", addListener);
                    div.removeEventListener("mouseleave", addListener);
                    return;
                }
                // no need to get root.
                t.removeEventListener("mouseenter", addListener);
                t.removeEventListener("mouseleave", addListener);
            });
        }
    }

    function getSwitch() {
        return GM_getValue("switch", true);
    }

    function addListener() {
        // the hover is at root.
        if (this.tagName === "DIV") {
            const target = this.parentElement.querySelector("img") || this.parentElement.querySelector("video");
            if (!target) return;
            target.style.opacity = target.style.opacity > 0.5 ? 0.1 : 1;
            return;
        }
        // no need to get root.
        this.style.opacity = this.style.opacity > 0.5 ? 0.1 : 1;
    }

    function css() {
        const style = document.createElement("style");
        style.type = "text/css";
        style.innerHTML = textStyle;
        document.head.appendChild(style);
    }

    function update() {
        if (updating) return;
        updating = true;
        init(3);
        setTimeout(() => { updating = false }, 1000);
    }

    function locationChange() {
        window.addEventListener('locationchange', () => init(3));
        // situation 1
        history.pushState = ( f => function pushState(){
            var ret = f.apply(this, arguments);
            window.dispatchEvent(new Event('pushState'));
            window.dispatchEvent(new Event('locationchange'));
            return ret;
        })(history.pushState);
        // situation 2
        history.replaceState = ( f => function replaceState(){
            var ret = f.apply(this, arguments);
            window.dispatchEvent(new Event('replaceState'));
            window.dispatchEvent(new Event('locationchange'));
            return ret;
        })(history.replaceState);
        // situation 3
        window.addEventListener('popstate', () => window.dispatchEvent(new Event('locationchange')));
    }

})();