YouTube Shorts — одна из наиболее раздражающих опций всеми любимого видеохостинга. YouTube агрессивно сует их везде, где только можно, превращая и без того не блещущую качеством контента выдачу в полноценную видеопомойку, где, чтобы найти нужный ролик, нужно буквально сесть и поковыряться. Впрочем, называть Shorts опцией не то чтобы корректно — ведь опция подразумевает возможность ситуативного подключения и отключения. А в случае с YouTube Shorts ничего подобного нет.
Зрителю будут навязывать просмотр Shorts вне зависимости от его желания. Хотите вы деградировать или нет, YouTube не интересно — за вас уже все решили. Более того, не интересно YouTube даже то, что вы пишете в поисковую строку. Ведь если 2–3 первых Shorts хотя бы номинально будут релевантными, то уже 4–5 в 9 из 10 случаев будут на рандомную тему, которую при всем желании не получится подвязать под ваши интересы. Хотя бы потому, что оно будет на английском, а вы не смотрите такое.
К счастью для тех, кого принято величаво называть ПК-бояре, отключить YouTube Shorts проще простого — достаточно накатить соответствующее расширение для браузера. О том, как его создать, мы и расскажем в сегодняшнем материале. Ну а если вы предпочитаете смотреть YouTube с экрана смартфона — ю ар велком.
Мы же перейдем к созданию нашего расширения.
Важные нюансы
Впрочем, сначала пара минут ликбеза. Если влом читать — листайте сразу в раздел ниже. Однако мы все же советуем прочесть этот раздел. Банально для того, чтобы вы не просто скопипастили «какой-то там» код, а хотя бы поверхностно понимали, что вообще происходит.
JavaScript — спешим обрадовать, изучать JS вам не придется. Тут как раз можно просто скопипастить. Однако о том, что вы будете им пользоваться, понимать нужно. В общем, любые ваши браузерные расширения — это всегда JS. Ну и файл-манифест. И другие вспомогательные файлы. Но JS будет в 100% случаев. Если мы, конечно, говорим о работающем расширении, а не о пустышке. Так вот взаимодействовать JS будут с DOM-элементами. Пока просто запомните это.
DIV и SPAN — это универсальные HTML-контейнеры, используемые каскадными таблицами стилей CSS. В свою очередь, CSS — это, так сказать, условия отображения веб-страницы. То, где приведено, как, что и где будет отображаться. В целом они не являются обязательными, но используются на любом более-менее сложном сайте. Грубо говоря, они давно стали частью HTML-верстки. Пусть технически это и не совсем верно.
DOM-деревья — объектные модели документов. Это то, как ваш браузер интерпретирует ранее упомянутые CSS, а также, в частности, их элементы DIV и SPAN, в понятный для видеоядра формат. Вообще говоря, речь не столько про CSS, сколько про чистый HTML, но это нам тоже не особо важно. Куда важнее, что любую страницу браузер «представляет» в формате DOM-дерева. И именно это DOM-дерево мы будем изменять.
Зачем нам все это знать? Все потому, что YouTube — сайт сложный. И даже если бы Google не старался специально усложнить жизнь тем, кто хочет отключить Shorts, названия DIV и SPAN все равно генерировались бы на ходу. Ведь иначе обеспечить динамическую подгрузку ленты просто не получится. Вернее, получится, но ценой забивания огромного количества места на серверах. А это Google ни к чему. Поэтому названия для DIV и SPAN генерируются прямо в вашем браузер в момент загрузки.
Какой из этого вывод? Правильно — узнать заранее названия DIV и SPAN и просто их не прогружать мы не сможем. Соответственно, мы будем сначала грузить страницу целиком, а затем с помощью JavaScript вырезать ненужные нам DOM-элементы уже при рендере (отрисовке). И вот тут зарыт главный нюанс: любое обновление интерфейса может сломать наше расширение. Это важно заранее понимать. Ведь единственное, на что мы будем ориентироваться, — это наличие слова «Shorts».
Впрочем, может сломать, а может и не сломать. Посему — начнем!
Создаем расширение, убирающее Shorts на YouTube
Как мы уже писали ранее, расширения состоят из манифеста и JS. Посему создадим манифест.
Для этого:
- Создаем текстовый редактор.
- Вставляем следующих код:
{
"manifest_version": 3, "name": "Нахуй Shorts",
"version": "1.0",
"description": "Расширение удаляет YouTube Shorts из разных частей интерфейса YouTube, включая поиск, главную страницу и блоки рекомендаций, динамически фильтруя элементы DOM.",
"action": {
"default_title": "Нахуй Shorts",
"default_description": "Удаляет Shorts из интерфейса YouTube"
},
"content_scripts": [
{
"matches": [
"*://*.youtube.com/*"
],
"js": [
"content.js"
],
"run_at": "document_idle"
}
],
"permissions": [
"scripting"
],
"host_permissions": [
"*://*.youtube.com/*"
]
} - Сохраняем как manifest.json
Также нам нужно создать наш JavaScript, для этого:
- Создаем текстовый редактор.
- Вставляем следующих код:
(function () {
const CONFIG = { DEBUG: false,
INTERVAL_MS: 1000,
ENABLE_OBSERVER: true
};
const SELECTORS = {
GRID_SHELF: "grid-shelf-view-model",
SHORTS_LINK: 'a[href*="/shorts/"]',
VIDEO_RENDERERS: [
"ytd-video-renderer",
"ytd-rich-item-renderer",
"ytd-grid-video-renderer",
"ytd-reel-item-renderer"
].join(","),
SHELVES: "ytd-reel-shelf-renderer, ytd-rich-shelf-renderer",
REEL_ITEMS: "ytd-reel-item-renderer"
};
function log(...args) {
if (!CONFIG.DEBUG) return;
console.log("[ShortsKiller]", ...args);
}
function removeGridShelves() {
const nodes = document.querySelectorAll(SELECTORS.GRID_SHELF);
nodes.forEach((el, i) => {
try {
log("Removing grid shelf:", i);
el.remove();
} catch (e) {
log("Error removing grid shelf", e);
}
});
}
function removeShortsByLinks() {
const links = document.querySelectorAll(SELECTORS.SHORTS_LINK);
links.forEach((a, i) => {
try {
const block = a.closest(SELECTORS.VIDEO_RENDERERS);
if (block) {
log("Removing Shorts block via link:", i);
block.remove();
}
} catch (e) {
log("Error removing Shorts link block", e);
}
});
}
function removeShortsShelves() {
const shelves = document.querySelectorAll(SELECTORS.SHELVES);
shelves.forEach((el, i) => {
try {
const text = el.innerText || "";
if (text.includes("Shorts")) {
log("Removing shelf:", i);
el.remove();
}
} catch (e) {
log("Error removing shelf", e);
}
});
}
function removeReelItems() {
const items = document.querySelectorAll(SELECTORS.REEL_ITEMS);
items.forEach((el, i) => {
try {
log("Removing reel item:", i);
el.remove();
} catch (e) {
log("Error removing reel item", e);
}
});
}
function killShortsEverywhere() {
log("Running cleanup cycle...");
removeGridShelves();
removeShortsByLinks();
removeShortsShelves();
removeReelItems();
log("Cleanup finished.");
}
function startObserver() {
if (!CONFIG.ENABLE_OBSERVER) return;
const observer = new MutationObserver(() => {
killShortsEverywhere();
});
observer.observe(document.body, {
childList: true,
subtree: true
});
log("MutationObserver started");
}
function startInterval() {
setInterval(() => {
killShortsEverywhere();
}, CONFIG.INTERVAL_MS);
log("Interval cleanup started");
}
function init() {
log("Initializing ShortsKiller...");
killShortsEverywhere();
startObserver();
startInterval();
log("Init complete");
}
init();
})(); - Сохраняем как content.js.
Теперь нам нужно, собственно, превратить все это в расширение:
- Закидываем оба файла в одну папку (в идеале без кириллицы в названии или по пути к ней, но на современных ОС в целом без разницы).
- Открываем Chrome, тыкаем на «три точки».
- Затем тыкаем на «Расширения».
- После на «Управление расширениями».
- Находим «Загрузить распакованное расширение».
- Выбираем ранее созданную папку.
Тестируем.
Как оно работает?
Вероятно, кто-то из тех, кто в теме, мог задаться вопросом: а нафига делать так сложно-то? Ну…
Вспоминаем про DOM-дерево из раздела «Нюансы». По мере прокрутки ленты браузер постоянно добавляет новые элементы в уже существующую структуру. Посему единожды удалить Shorts не получится. Новые блоки будут появляться постоянно, а вместе с ними и Shorts. Именно поэтому мы и добавили динамический MutationObserver, удаляющий ранее не существующие DOM-элементы каждые 1000 миллисекунд, если они попадают под наши критерии определения Shorts.
В итоге скрипт работает следующим образом:
- Удаляет все элементы DOM, связанные с grid-shelf-view-model.
- Находит ссылки вида /shorts/ и удаляет их родительские видеокарточки.
- Убирает shelf-блоки (горизонтальные секции), если в них встречается слово «Shorts».
- Удаляет отдельные reel-элементы, используемые YouTube для Shorts-контента.
- Запускает первичную очистку сразу после загрузки страницы.
- Постоянно отслеживает изменения DOM через MutationObserver.
Не очень рационально с точки зрения оптимизации — зато надежно. В теории может лагать. Но на современных машинах — маловероятно. По уму, проверку раз в секунду следовало бы заменить на проверку при подгрузке новых элементов, но как это реализовать, автор так и не смог разобраться ¯\_(ツ)_/¯. Да и 1000 миллисекунд всегда можно заменить на другое значение, если будет лагать.
Саммари
Как видите, создать расширение, убирающее Shorts на YouTube, не так уж и сложно. Надеемся, свой интерфейс YouTube обновит еще не скоро, и наш скриптик надолго защитит ПК-бояр от брейнрот-контента. Ну а решением для тех, кто везде носит с собой смартфон, мы уже делились не так давно. Следите за нашей Телегой, чтобы не пропустить новые полезные скрипты!