Список пользователей

1
Админ
Постов: 101
2
Элита
Постов: 34
3
Элита
Постов: 28
4
VIP
Постов: 26
5
Дизайнер
Постов: 25
6
Пользователи
Постов: 25
7
Пользователи
Постов: 24
8
Проверенные
Постов: 21

  • Страница 1 из 1
  • 1
Личные сообщения скрипт подставляет аватарки UCOZ V3
Дата: Вторник, 14.10.2025, 06:12 | Сообщение # 1 | | Написал: Начинающий
Автор темы
Мурчанн не в сети
        Сообщений:101
         Регистрация:20.10.2016

Да это финальный скрипт, подставляющий аватарки в сообщения.
Он работает в двух направлениях: в списке сообщений и внутри письма подставляет авы; размеры расширены и настроены.

Единственный недостаток: дефолтная аватарка не подставляется, если пользователь не загрузил свою картинку в профиль.

Думаю, проблема не в скрипте, а в моём сайте , он старый и глючный, с множеством багов.

Возможно, дело в системе uCoz, и эту проблему решить сложно.

Я оставлю вам скрипт возможно, вы сможете её устранить.

Передаю эстафету вам друзья. 27

в конце шаблона в личных сообщения перед закрывающем тегом
Код
</body>
ставите скрипт .

Код
<script>
(function(){
'use strict';

const DEFAULT_AVATAR = "https://jordan.moy.su/ava/avapm.png";
const CHECK_DELAY = 100;

let avatarMap = {}; // key = href или name

function applyAvatar(container, key){
    if(!container) return;

    let overlay = container.querySelector('.avatarOverlay');
    if(!overlay){
        overlay = document.createElement('div');
        overlay.className = 'avatarOverlay';
        overlay.style.position = 'absolute';
        overlay.style.top = '0';
        overlay.style.left = '-2px'; // сдвигаем на 10px влево
        overlay.style.width = '60px';  // ширина контейнера
        overlay.style.height = '72px'; // высота контейнера

        overlay.style.display = 'flex';
        overlay.style.justifyContent = 'center';
        overlay.style.alignItems = 'center';
         overlay.style.paddingTop = '-5px';   // визуальное опускание
        overlay.style.paddingBottom = '10px';
        overlay.style.overflow = 'hidden';
        overlay.style.zIndex = '10';
        if(getComputedStyle(container).position==='static') container.style.position='relative';
        container.appendChild(overlay);
    }

    let img = overlay.querySelector('img');
    if(!img){
        img = document.createElement('img');
        img.style.maxWidth = '100%';
        img.style.maxHeight = '100%';
        img.style.objectFit = 'cover';
        img.style.objectPosition = 'center';
        img.style.margin = 'auto';
        img.style.display = 'block';
        overlay.appendChild(img);
    }

    // Жёсткая логика: если аватар найден в карте — используем, иначе дефолт
    img.src = avatarMap[key] || DEFAULT_AVATAR;
    img.alt = '';
}

// Определяем отправителя
function findSender(row){
    if(!row) return null;
    const fromCell = row.querySelector('td:nth-child(2), td:nth-child(3), .nick, .username');
    if(fromCell){
        const a = fromCell.querySelector('a[href*="/index/8-0-"], a[href*="/users/"], a.profile-link');
        if(a) return {href:a.href, name:a.textContent.trim()};
        return {name: fromCell.textContent.trim()};
    }
    return null;
}

// Асинхронно ищем реальную аву
async function fetchAvatar(identifier){
    if(!identifier) return null;
    const key = identifier.href || identifier.name;

    if(avatarMap[key] && avatarMap[key] !== DEFAULT_AVATAR) return avatarMap[key];

    const urls = identifier.href ? [identifier.href] : [
        location.origin + '/index/8-0-' + encodeURIComponent(identifier.name.replace(/\s+/g,'-')),
        location.origin + '/index/8-0-' + encodeURIComponent(identifier.name)
    ];

    for(const url of urls){
        try {
            const res = await fetch(url, {cache:'no-cache'});
            if(!res.ok) continue;
            const html = await res.text();
            const doc = new DOMParser().parseFromString(html, "text/html");
            const img = doc.querySelector('img[src*="/avatar/"], img[src*="/ava/"], .user_avatar img, .avatar img, .profile-picture img');
            if(img && img.src && !/noavatar|default|empty/i.test(img.src)){
                avatarMap[key] = new URL(img.src, url).href;
                return avatarMap[key];
            }
        } catch(e){}
        await new Promise(r=>setTimeout(r, CHECK_DELAY));
    }

    return null; // если авы нет — дефолт остаётся
}

// Обработка строк сообщений
async function processRows(){
    const rows = Array.from(document.querySelectorAll('.userpm-messages-table tr[id^="ent"], .pm-list tr, tr.pm-row'));
    for(const row of rows){
        if(row.dataset._avatarInjected==='1') continue;

        const identifier = findSender(row);
        const cell = row.querySelector('.r_round, .avatar, .pm_avatar, td:first-child, td.avatar-cell');
        if(identifier && cell){
            const key = identifier.href || identifier.name;

            // Сначала дефолтная аватарка
            applyAvatar(cell, key);

            // Асинхронно подставляем реальную аву
            fetchAvatar(identifier).then(realSrc=>{
                if(realSrc) applyAvatar(cell, key);
                // если realSrc null — дефолт останется
            });
        }

        row.dataset._avatarInjected='1';
    }
}

// Открытые PM
async function processOpenPMs(){
    const openPMs = Array.from(document.querySelectorAll('.userpm-message-table'));
    for(const pm of openPMs){
        if(pm.dataset._avatarInjected==='1') continue;

        const header = pm.querySelector('.userpm-message-subject, .pm-header, .pm-author');
        const link = pm.querySelector('a[href*="/index/8-0-"], a[href*="/users/"]');
        const identifier = link ? {href:link.href, name:link.textContent.trim()} : header ? {name:header.textContent.trim()} : null;
        const target = pm.querySelector('.r_round, .avatar, .pm_avatar, .userpm-message-subject') || pm;

        if(identifier && target){
            const key = identifier.href || identifier.name;

            // Дефолт для отправителя
            applyAvatar(target, key);

            // Асинхронно реальная
            fetchAvatar(identifier).then(realSrc=>{
                if(realSrc) applyAvatar(target, key);
            });
        }

        pm.dataset._avatarInjected='1';
    }
}

// Инициализация
function init(){
    processRows();
    processOpenPMs();
    const obs = new MutationObserver(()=>{
        processRows();
        processOpenPMs();
    });
    obs.observe(document.body, {childList:true, subtree:true});
}

// Стили
(function addStyles(){
    const st = document.createElement('style');
    st.textContent = `
        .avatarOverlay img{
            transform-origin: center center;
        }
        .avatarOverlay img:hover{
            transform: scale(1.04);
            transition: transform .18s ease;
        }`;
    document.head.appendChild(st);
})();

if(document.readyState==='loading') document.addEventListener('DOMContentLoaded', init); else init();

})();
</script>






Да, так бывает в жизни
когда все дороги кажутся исчерпанными,
когда упираешься в невозможное,
в баги, глюки, в саму матрицу…
Жизнь слишком сложна, чтобы считать её простой,
она плетёт свои узоры из хаоса и чудес. 2

Мурчанн

Признаюсь, не знаю почему, но глядя на звезды мне всегда хочется мечтать.
  • Страница 1 из 1
  • 1
Поиск: