У одного известного сайта конфликт с черногорским(?) регистратором доменов. В результате ему пришлось срочно переехать с домена t.me, на домен telegram.me. Часть веб-страниц поломалась, т.к. пытаются качать IFRAME-ы со старого домена.
Гугло-ИИ предложил короткий скрипт, который работал, но высота IFRAME была неверной. После долгой беседы DeepSeek выдал такой скрипт:
// ==UserScript==
// @name t.me corrector
// @namespace http://tampermonkey.net/
// @version 2026-07-14
// @description replace "t.me" with "telegram.me"
// @author DeepSeek
// @match https://telegram.me/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Функция замены домена
function replaceDomain(url) {
try {
const urlObj = new URL(url, window.location.href);
if (urlObj.hostname.includes('t.me')) {
urlObj.hostname = urlObj.hostname.replace(/t\.me/g, 'telegram.me');
return urlObj.toString();
}
} catch (_) {}
return url.replace(/t\.me/g, 'telegram.me');
}
// Функция подстройки высоты одного iframe
function autoHeightIframe(iframe) {
// Сначала убираем прокрутку и задаём начальную высоту
iframe.style.overflow = 'hidden';
//iframe.scrolling = 'no'; // для старых браузеров
iframe.style.height = '100px'; // временная, чтобы сработало
const adjustHeight = () => {
try {
// Доступ к содержимому возможен, т.к. домен совпадает
const doc = iframe.contentDocument || iframe.contentWindow.document;
if (!doc) return;
// Вычисляем высоту содержимого (body + margin)
const body = doc.body;
const html = doc.documentElement;
const height = Math.max(
body.scrollHeight,
body.offsetHeight,
html.clientHeight,
html.scrollHeight,
html.offsetHeight
);
// Устанавливаем новую высоту с небольшим запасом (опционально)
iframe.style.height = height + 'px';
} catch (e) {
// Если доступ запрещён (неожиданно) – игнорируем
}
};
// Подстраиваем после полной загрузки iframe
iframe.addEventListener('load', () => {
adjustHeight();
// Настраиваем отслеживание изменений внутри iframe
//setupObservers(iframe);
});
// Если iframe уже загружен (например, src установлен ранее)
if (iframe.contentDocument && iframe.contentDocument.readyState === 'complete') {
adjustHeight();
//setupObservers(iframe);
}
}
/*
// Настройка наблюдателей за изменениями внутри iframe
function setupObservers(iframe) {
try {
const doc = iframe.contentDocument;
if (!doc) return;
const target = doc.body;
if (!target) return;
// 1. ResizeObserver – отслеживает изменение размера элементов
if (window.ResizeObserver) {
const resizeObserver = new ResizeObserver(() => {
// При изменении размера пересчитываем высоту
const height = Math.max(
doc.body.scrollHeight,
doc.documentElement.scrollHeight,
doc.body.offsetHeight,
doc.documentElement.offsetHeight
);
iframe.style.height = height + 'px';
});
resizeObserver.observe(target);
// Также наблюдаем за html, так как изменения могут быть там
resizeObserver.observe(doc.documentElement);
}
// 2. MutationObserver – отслеживает добавление/удаление узлов
const mutationObserver = new MutationObserver(() => {
// Пересчёт высоты после изменения DOM
const height = Math.max(
doc.body.scrollHeight,
doc.documentElement.scrollHeight,
doc.body.offsetHeight,
doc.documentElement.offsetHeight
);
iframe.style.height = height + 'px';
});
mutationObserver.observe(target, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['style', 'class', 'height', 'width']
});
} catch (e) {
// Если доступ запрещён – игнорируем
}
}
*/
// Обработка одного элемента
function processElement(el) {
if (el.tagName === 'IFRAME') {
// Заменяем src у iframe
const src = el.getAttribute('src');
if (src && src.includes('t.me')) {
el.setAttribute('src', replaceDomain(src));
// После замены src запускаем подстройку высоты
autoHeightIframe(el);
}
return; // Не обрабатываем другие атрибуты у iframe
}
// Для остальных элементов заменяем href, src, action
const attrs = ['href', 'src', 'action'];
for (const attr of attrs) {
if (el.hasAttribute(attr)) {
const value = el.getAttribute(attr);
if (value.includes('t.me')) {
el.setAttribute(attr, replaceDomain(value));
}
}
}
}
// Обработка всех существующих элементов
function processAllElements() {
document.querySelectorAll('[href], [src], [action]').forEach(processElement);
}
// Запуск после загрузки DOM
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', processAllElements);
} else {
processAllElements();
}
/*// Наблюдаем за динамически добавляемыми элементами
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (node.nodeType === Node.ELEMENT_NODE) {
processElement(node);
node.querySelectorAll('[href], [src], [action]').forEach(processElement);
}
}
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});*/
})();
Что в нём можно сократить? Помимо вызова observer.




