Разблокирует скролл ленты и чинит съехавшую верстку модальных окон (подписчики/подписки) в TikTok.
// ==UserScript==
// @name TikTok Scroll & Layout Fix
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Разблокирует скролл ленты и чинит съехавшую верстку модальных окон (подписчики/подписки) в TikTok.
// @author torch
// @match *://*.tiktok.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=tiktok.com
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 1. Добавляем CSS-правила с !important, которые не дадут TikTok сломать скролл и сдвинуть верстку
const style = document.createElement('style');
style.innerHTML = `
/* Возвращаем скроллбар и убираем сдвиг страницы (padding-right) */
html, body {
overflow-y: auto !important;
overflow-x: hidden !important;
padding-right: 0 !important;
margin-right: 0 !important;
}
/* Убираем атрибут блокировки напрямую через CSS для надежности */
body[data-scroll-locked] {
overflow: auto !important;
}
/* Чиним окно подписчиков, чтобы оно не улетало за пределы экрана и внутри него работал скролл */
[data-e2e="follow-info-popup"] {
max-height: 80vh !important;
display: flex !important;
flex-direction: column !important;
}
[data-e2e="follow-info-popup"] div[class*="DivUserListContainer"] {
overflow-y: auto !important;
overscroll-behavior: contain;
flex: 1 1 auto !important;
}
/* Запрещаем сдвиг для самого контейнера модального окна */
div[class*="ModalContainer"], div[class*="ModalContentContainer"] {
padding-right: 0 !important;
}
`;
document.head.appendChild(style);
// 2. Используем MutationObserver для перехвата скриптов TikTok,
// которые пытаются повесить блокировку в реальном времени.
const observer = new MutationObserver((mutations) => {
let shouldFix = false;
mutations.forEach((mutation) => {
if (mutation.type === 'attributes') {
shouldFix = true;
}
});
if (shouldFix) {
const body = document.body;
// Принудительно удаляем атрибут, блокирующий скролл
if (body.hasAttribute('data-scroll-locked')) {
body.removeAttribute('data-scroll-locked');
}
// Подчищаем инлайн-стили, сдвигающие контент
if (body.style.overflow === 'hidden') {
body.style.overflow = '';
}
if (body.style.paddingRight) {
body.style.paddingRight = '';
}
}
});
// Запускаем наблюдение за тегом <body>
observer.observe(document.body, {
attributes: true,
attributeFilter: ['data-scroll-locked', 'style', 'class']
});
// 3. Выполняем первичную очистку на случай, если страница уже загрузилась сломанной
if (document.body.hasAttribute('data-scroll-locked')) {
document.body.removeAttribute('data-scroll-locked');
}
document.body.style.overflow = '';
document.body.style.paddingRight = '';
})();