Дата: Пятница, 26.12.2025, 15:14 | Сообщение # 1 |
|
Написал: Узнаваемый
Автор темы
Мурчанн
не в сети
Сообщений: 162
Продолжаем совершенствовать модуль вывода блока друзей на любую часть сайта. В текущей версии реализовано всплывающее окно со списком друзей, стилизованное под стиль ВКонтакте. При этом отображается только сам список друзей, без дополнительных настроек и возможности удаления. Теоретически можно подтянуть и другие данные, но для этого потребуется модифицировать вид материала блога, так как именно через этот модуль осуществляется вывод друзей. Скрипт создаёт записи в модуле и скрывает их. В настройках модуля вывод материалов ограничен до 50, что означает, что одновременно будет отображаться максимум 50 друзей. В будущем мы ждём полноценный модуль «Друзья» от платформы uCoz. Пока же продолжаем использовать кастомные версии. Создаем глобальный блок и вставляем. Код
<style> /* ===== БАЗОВЫЙ КОНТЕЙНЕР ===== */ .vk-old-block { background: #fff; border: 1px solid #d1d5da; font-family: Tahoma, Arial, sans-serif; font-size: 13px; color: #000; width: 100%; max-width: 600px; } .vk-old-header { background: #f0f2f5; padding: 6px 8px; border-bottom: 1px solid #d1d5da; color: #45688e; font-weight: bold; } .vk-old-content { padding: 10px 8px; } .vk-old-footer { background: #f7f7f7; border-top: 1px solid #d1d5da; padding: 5px 8px; color: #666; font-size: 13px; } /* ===== СПИСОК ДРУЗЕЙ ===== */ .vk-friends { display: flex; flex-wrap: wrap; gap: 10px 15px; } .vk-friend { width: 88px; text-align: center; cursor: pointer; position: relative; } .vk-friend img { width: 78px; height: 78px; border-radius: 50%; object-fit: cover; display: block; margin: 0 auto; transition: 0.3s ease; } .vk-friend span { display: block; margin-top: 4px; color: #45688e; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .vk-friend:hover::after { content: ''; position: absolute; top:0; left:0; width:100%; height:88%; border-radius:50%; background: rgba(0,0,0,.3); } /* ===== POPUP ===== */ .vk-friends-overlay { position: fixed; inset:0; background: rgba(0,0,0,.35); z-index: 9999; display: flex; align-items: center; justify-content: center; } .vk-friends-popup { width: 420px; max-height: 520px; background: #fff; border-radius: 6px; display: flex; flex-direction: column; overflow: hidden; font-family: Tahoma, Arial, sans-serif; box-shadow: 0 8px 30px rgba(0,0,0,.25); animation: vkPop .18s ease-out; } @keyframes vkPop { from {transform: scale(.96);opacity:0;} to {transform: scale(1);opacity:1;} } .vk-friends-popup-header { background: #f0f2f5; padding: 8px 12px; font-weight: bold; color: #45688e; display: flex; justify-content: space-between; align-items: center; border-bottom:1px solid #d1d5da; } .vk-friends-popup-close { cursor:pointer; font-size:18px; color:#FFF; } .vk-friends-popup-close:hover {color:#000;} .vk-friends-popup-list { flex:1; overflow-y:auto; padding:6px 0; } /* POPUP СТИЛИ */ .vk-friends-overlay { position: fixed; top:0; left:0; width:100%; height:100%; background: rgba(0,0,0,0.5); z-index: 9999; } .vk-friends-popup { background:#fff; max-width:400px; width:90%; margin:50px auto; border-radius:8px; overflow:hidden; font-family:Arial, sans-serif; } .vk-friends-popup-header { padding:10px; background:#5181b8; color:#fff; font-weight:bold; display:flex; justify-content:space-between; align-items:center; } .vk-friends-popup-close { cursor:pointer; font-size:18px; } .vk-friends-popup-list { max-height:800px; overflow-y:auto; } .vk-friends-row { display:flex; align-items:center; padding:5px 10px; cursor:pointer; transition: background 0.2s; } .vk-friends-row:hover { background: #f0f0f0; /* только фон */ } .vk-friends-row img { width:36px; height:36px; border-radius:50%; margin-right:10px; } .vk-friends-row-name { font-weight:bold; } .vk-icon { display:inline-block; width:16px; height:16px; line-height:16px; text-align:center; border-radius:50%; font-size:11px; color:#fff; font-weight:bold; margin-left:5px; } .vk-icon.friend { background-color:#5181b8; } /* синий */ .vk-icon.family { background-color:#e4433c; } /* красный */ .vk-icon.work { background-color:#7ac74f; } /* зелёный */ .vk-icon.idol { background-color:#f7b500; color:#000;} /* жёлтый */ .vk-icon.acquaintance { background-color:#a9a9a9; } /* серый */ /* ===== ДРУЖЕСКИЕ СТРОКИ ===== */ .vk-friends-row { display:flex; align-items:center; gap:12px; padding:8px 12px; border-bottom:1px solid #edf1f5; cursor:pointer; transition: background .15s ease, padding-left .15s ease; } .vk-friends-row:last-child {border-bottom:none;} .vk-friends-row img { width:80px; height:80px; border-radius:50%; object-fit:cover; box-shadow:0 0 0 1px rgba(0,0,0,.08); transition: transform .15s ease; } </style> <div class="vk-old-block"> <div class="vk-old-header">Друзья</div> <div class="vk-old-footer" id="friends-count">0 друзей</div> <div class="vk-old-content"> <div class="vk-friends"></div> </div> </div> <script> $(function(){ <?if(!$USER_LOGGED_IN$)?> $('#friends-count').text('Друзей нет'); $('.vk-friends').empty(); return; <?else?> const USER_ID = '$_USER_ID$'; const CACHE_KEY = 'friends_' + USER_ID; const CACHE_TIME_KEY = CACHE_KEY + '_time'; const CACHE_TTL = 24 * 60 * 60 * 1000; const $container = $('.vk-friends'); const $counter = $('#friends-count'); const DEFAULT_AVA = '/.s/src/profile/img/profile_photo_thumbnail.png'; let allFriends = []; /* ===== ФУНКЦИЯ ОТОБРАЖЕНИЯ МИНИ-БЛОКА ===== */ function renderMini(friends){ $container.empty(); friends.slice(0,6).forEach(f => { const card = $(` <div class="vk-friend" title="${f.nick}"> <img src="${f.ava}"> <span>${f.nick}</span> </div> `); card.on('click',()=>location.href=f.profile); $container.append(card); }); $counter.text(friends.length + ' друзей'); } /* ===== POPUP С ДРУЗЬЯМИ ===== */ function showPopup(){ if(!allFriends.length) return; const overlay = $('<div class="vk-friends-overlay"></div>'); const popup = $(` <div class="vk-friends-popup"> <div class="vk-friends-popup-header"> Друзья (${allFriends.length}) <span class="vk-friends-popup-close">×</span> </div> <div class="vk-friends-popup-list"></div> </div> `); popup.find('.vk-friends-popup-close').on('click',()=>overlay.remove()); overlay.on('click', e => { if(e.target === overlay[0]) overlay.remove(); }); const list = popup.find('.vk-friends-popup-list'); allFriends.forEach(f => { // Иконка статуса в стиле ВК let iconClass = 'friend'; let iconLetter = 'Д'; const g = f.group.toLowerCase(); if(g.includes('сем')) { iconClass = 'family'; iconLetter = 'С'; } else if(g.includes('коллег')) { iconClass = 'work'; iconLetter = 'К'; } else if(g.includes('кумир')) { iconClass = 'idol'; iconLetter = 'К'; } else if(g.includes('знаком')) { iconClass = 'acquaintance'; iconLetter = 'З'; } const row = $(` <div class="vk-friends-row"> <img src="${f.ava}"> <div class="vk-friends-row-info"> <div class="vk-friends-row-name"> ${f.nick} <span class="vk-icon ${iconClass}">${iconLetter}</span> </div> <div class="vk-friends-row-group"> ${f.group} </div> </div> </div> `); row.on('click',()=>location.href=f.profile); list.append(row); }); overlay.append(popup); $('body').append(overlay); } /* ===== ЗАГРУЗКА ДРУЗЕЙ ===== */ function fetchFriends(){ const cached = localStorage.getItem(CACHE_KEY); const time = localStorage.getItem(CACHE_TIME_KEY); if(cached && time && Date.now()-time < CACHE_TTL){ allFriends = JSON.parse(cached); renderMini(allFriends); } $.get('/blog/0-0-1-0-17-' + USER_ID, html=>{ const $tmp = $('<div>').html(html); const $items = $tmp.find('.friend'); allFriends = []; $items.each(function(){ const $el = $(this); allFriends.push({ nick: $el.find('.nick').text().trim(), ava: $el.find('.ava').text().trim() || DEFAULT_AVA, profile: $el.find('.url').text().trim(), group: $el.find('.gr').text().trim() || 'Без статуса' }); }); localStorage.setItem(CACHE_KEY, JSON.stringify(allFriends)); localStorage.setItem(CACHE_TIME_KEY, Date.now()); renderMini(allFriends); }); } /* ===== ИНИЦИАЛИЗАЦИЯ ===== */ $counter .css('cursor','pointer') .attr('title','Показать всех друзей') .on('click', showPopup); fetchFriends(); <?endif?> }); </script>
Признаюсь, не знаю почему, но глядя на звезды мне всегда хочется мечтать.