Скрипт предназначен для автоматического отображения аватарок пользователей форума (или комментариев) даже в тех местах, где стандартный движок их не показывает. Он находит ник пользователя на странице, подгружает его профиль и извлекает ссылку на изображение-аватар, после чего вставляет её прямо в интерфейс.
Ночной охотник за аватарками - продвинутый стратегический скрипт
Что делает:
1. Находит ник последнего комментатора и пытается подгрузить его аватар. 2. Использует кеш (localStorage), карту userMap и парсинг профилей. 3. Перебирает несколько кандидатных URL и резервных селекторов. 4. Фильтрует дефолтные/системные картинки, ставит только корректные авы.
Поведение:
1. Работает автономно, устойчив к неудачам и CORS; логирует процесс в консоль. 2. Логика подробно описана в теле скрипта - читайте, чтобы понять, как он достигает цели.
Лозунг: Работает по ночам, находит всегда.
Добавлено
Кэширование результата.
Чтобы не перегружать сервер, скрипт сохраняет результат в LocalStorage браузера. Это значит, что при повторных загрузках страницы он не делает новые запросы, а использует сохранённые данные. Благодаря этому страница грузится быстрее, а сервер не получает лишних обращений.
Интеллектуальное обновление кэша.
В усовершенствованной версии добавлен таймер жизни кэша (TTL) — например, 6 часов. Если прошло больше времени, чем указано, или у пользователя раньше не было аватарки, скрипт проверяет данные заново. Это позволяет автоматически подгружать новые аватары, если пользователь их сменил.
Визуальное применение. После получения ссылки на изображение скрипт вставляет в нужный элемент страницы — например, рядом с ником, в карточку пользователя или в блок комментариев.
Код
<script> /* Авто-подстановка аватаров — улучшенная отладочная версия (v3.5) - добавлено авто-обновление кэша каждые 6 часов (TTL) - повторная проверка, если в кэше была дефолтная аватарка - расширенный лог для диагностики */
function getLastCommentInfo(topicEl){ const lastBlock = topicEl.querySelector('.last_post, .lastpost, .last-post'); let anchor = null; if(lastBlock){ anchor = lastBlock.querySelector('.uLPost, a, .lastpost_author a, .username, .user a'); } if(!anchor){ anchor = topicEl.querySelector('.last_post .uLPost, .last_post a, .uLPost, .last_post span a, a[href*="/index/8-"], a[href*="/user/"], .last_user a, .lastpost_author a, .username a'); } if(!anchor) return null; const username = (anchor.textContent || '').trim(); const href = anchor.getAttribute('href') || null; return { username: username || null, href: href }; }
function findAvatarImgElement(topicEl){ let lastBlock = topicEl.querySelector('.last_post, .lastpost, .last-post'); if(lastBlock){ const img = lastBlock.querySelector('img[class*="avatar"], img.ipsUserPhoto, .user_avatar img, img.profile-avatar'); if(img) return img; } const uL = topicEl.querySelector('.uLPost, .lastpost_author, .last_user'); if(uL){ const maybe = uL.querySelector('img[class*="avatar"], img.ipsUserPhoto, img.profile-avatar'); if(maybe) return maybe; } const infoAnchor = topicEl.querySelector('.last_post a, .last_post .uLPost, .lastpost_author a, .last_user a, a[href*="/index/8-"], a[href*="/user/"]'); if(infoAnchor){ let p = infoAnchor.parentElement; for(let i=0;i<4 && p;i++, p = p.parentElement){ const img = p.querySelector('img[class*="avatar"], img.ipsUserPhoto, img.profile-avatar, .user_avatar img'); if(img) return img; } } return null; }
async function handleTopic(topicEl){ try{ const avatarImg = findAvatarImgElement(topicEl); if(!avatarImg){ console.debug('autoAvatar: avatar element not found for topic', topicEl); return; } if(avatarImg.dataset.autoAvatarDone) return; avatarImg.dataset.autoAvatarDone = '1';
const info = getLastCommentInfo(topicEl); if(!info || !info.username){ console.debug('autoAvatar: no last author info for topic'); return; }