// ==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 // @downloadURL none // ==/UserScript== /* jshint esversion: 6 */ (function() { 'use strict'; // icons made by https://www.flaticon.com/authors/pixel-perfect const iconOn = ``; const iconOff = ``; // 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'))); } })();