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

1
Админ
Постов: 211
2
VIP
Постов: 72
3
Элита
Постов: 50
4
Проверенные
Постов: 35
5
VIP
Постов: 35
6
Проверенные
Постов: 32
7
Пользователи
Постов: 31
8
Проверенные
Постов: 29

  • Страница 1 из 1
  • 1
Модуль ВК «Подписки » для Ucoz v 5.0 стиль февраль 2026
Дата: Среда, 18.02.2026, 12:51 | Сообщение # 1 | | Написал: Узнаваемый
Автор темы
Мурчанн не в сети
        Сообщений:211
         Регистрация:20.10.2016

Февральский стиль сдержанный, в серо-белых тонах, минималистичный.
Пока ничего лучше придумать не удалось. Скрипт и основной блок остались без изменений корректировки внесены только в CSS-стили и настройки.



Исходной код

Код
<!-- ======= Блок подписок ======= -->

<div class="vksub-block">
<div class="vksub-head">
<span>Подписки</span>
<span class="vksub-count" id="subsCount">
<span class="subs-label">Подписок</span>
<span class="subs-number">0</span>
</span>
</div>
<div class="vksub-container" id="subsParser">
<div class="vksub-empty">Загрузка подписок...</div>
</div>
</div>

<script>
(async function() {

const container = document.getElementById('subsParser');
const counter = document.getElementById('subsCount');
const parser = new DOMParser();
const forumURL = '/forum/0-0-1-46';
const localKey = 'cachedSubs';
const MAX_ITEMS = 5; // ограничение на количество выводимых материалов

/* ===================== КЛИК ПО СЧЁТЧИКУ ===================== */
if(counter){
counter.style.cursor = 'pointer';
counter.title = 'Перейти к списку подписок';
counter.onclick = () => window.location.href = forumURL;
}

/* ===================== ПОКАЗ КЭША ===================== */
let cached = JSON.parse(localStorage.getItem(localKey) || 'null');
if(cached){
container.className='';
container.innerHTML = cached.html;
if(counter.querySelector('.subs-number')) {
counter.querySelector('.subs-number').textContent = cached.count;
}
}

try {
/* ===== грузим страницу подписок ===== */
let page = await fetch(forumURL, {credentials:'include'});
let html = await page.text();
let doc = parser.parseFromString(html,'text/html');

// Получаем все темы, но ограничиваем вывод MAX_ITEMS
let rowsAll = doc.querySelectorAll('tr[id^="tt"]');
let totalCount = rowsAll.length;
let rows = Array.from(rowsAll).slice(0, MAX_ITEMS);

if(counter.querySelector('.subs-number')) {
counter.querySelector('.subs-number').textContent = `${rows.length} | ${totalCount}`;
}

if(cached && cached.count === totalCount) return;

if(!rows.length){
container.className = "vksub-empty";
container.textContent = "Нет подписок";
if(counter.querySelector('.subs-number')) {
counter.querySelector('.subs-number').textContent = "0";
}
localStorage.removeItem(localKey);
return;
}

let resultHTML = '';
let delay = 0;

/* ===================== ЦИКЛ ТЕМ ===================== */
for(let row of rows){

let topicEl = row.querySelector('.topic-item-title');
if(!topicEl) continue;

let topic = topicEl.textContent.trim();
let topicLink = topicEl.href;

let avatar = '/.s/img/icon/user.png';
let topicDesc = '';

try{
let topicPage = await fetch(topicLink,{credentials:'include'});
let topicHTML = await topicPage.text();
let topicDoc = parser.parseFromString(topicHTML,'text/html');

let firstImg = topicDoc.querySelector('.post-content-main img');
if(firstImg && firstImg.src) avatar = firstImg.src;

let thDescrEl = topicDoc.querySelector('span.thDescr');
topicDesc = thDescrEl ? thDescrEl.textContent.trim() : '';

}catch(e){
console.warn('Не удалось получить тему', topicLink);
}

/* ===== HTML В СТИЛЕ СТАРОГО CSS ===== */
resultHTML += `
<div class="vksub-item" style="animation-delay:${delay}ms" onclick="location.href='${topicLink}'">
<img class="vksub-avatar" src="${avatar}" alt="">
<div class="vksub-info">
<div class="vksub-name">
<a href="${topicLink}">${topic}</a>
</div>
${topicDesc
? `<div class="vksub-desc" style="font-style:italic;color:#555;margin-top:3px;">${topicDesc}</div>`
: ''}
</div>
<div class="vksub-indicator"></div>
</div>`;
delay += 40;
}

container.className = '';
container.innerHTML = resultHTML;

/* ===================== СОХРАНЯЕМ КЭШ ===================== */
localStorage.setItem(localKey, JSON.stringify({
count: totalCount,
html: resultHTML
}));

} catch(e){
if(!cached){
container.className = "vksub-empty";
container.textContent = "Ошибка загрузки подписок";
if(counter.querySelector('.subs-number')) {
counter.querySelector('.subs-number').textContent = "0";
}
}
console.error(e);
}

})();
</script>

<style>
/* ======= Стиль 2026 + миниатюризация ======= */
.vksub-block {
  background: #ffffff;
  border: 1px solid #ccd0d5;          /* серая граница */
  border-radius: 8px;                 /* мягкие скругления  */
  margin: 12px 0;
  overflow: hidden;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); /* очень лёгкая тень */
  font-size: 13px;
}

/* Шапка */
.vksub-head {
  background: #f0f2f5;                /* светлый фон */
  padding: 8px 12px;
  border-bottom: 1px solid #e4e6eb;
  font-size: 14px;
  font-weight: 600;
  color: #050505;                     /* почти чёрный текст */
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.vksub-head span:first-child {
  color: #050505;
}

/* Счётчик — как бейджик */
.vksub-count {
  display: inline-flex;
  align-items: center;
  font-size: 12px;
  color: #65676b;
}

.subs-label {
  color: #65676b;
  margin-right: 4px;
  font-weight: 500;
}

.subs-number {
  background: #e4e6eb;                /* серый бейджик */
  color: #050505;
  padding: 2px 7px;
  border-radius: 10px;
  font-weight: 600;
  min-width: 18px;
  text-align: center;
  font-size: 12px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.6);
}

.vksub-count:hover .subs-number {
  background: #d8dade;
}

/* Контейнер компактный как список в сайдбаре */
.vksub-container {
  max-height: 210px;                  /* минитюризация: короче для сайдбара */
  overflow-y: auto;
  padding: 4px 0;
  background: #fff;
}

/* Скроллбар в стиле (тонкий, серый) */
.vksub-container::-webkit-scrollbar {
  width: 6px;
}
.vksub-container::-webkit-scrollbar-track {
  background: transparent;
}
.vksub-container::-webkit-scrollbar-thumb {
  background: #c4c7cc;
  border-radius: 10px;
}
.vksub-container::-webkit-scrollbar-thumb:hover {
  background: #a0a4a9;
}

/* Элемент  */
.vksub-item {
  display: flex;
  align-items: center;
  padding: 8px 12px;
  cursor: pointer;
  transition: background 0.12s ease;
  border-radius: 6px;
  margin: 2px 4px;
  animation: fbFadeIn 0.25s ease;
}

.vksub-item:hover {
  background: #e4e6eb;                /* классический  hover */
}

.vksub-item:active {
  background: #d8dade;
}

/* Аватарка — круглая */
.vksub-avatar {
  width: 46px;                        /* минитюра: меньше, как в сайдбаре */
  height: 46px;
  border-radius: 50%;
  object-fit: cover;
  margin-right: 10px;
  border: none;
  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
  flex-shrink: 0;
}

/* Информация */
.vksub-info {
  flex: 1;
  min-width: 0;
}

.vksub-name {
  font-size: 13px;
  font-weight: 600;
  color: #050505;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.3;
}

.vksub-name a {
  color: #050505;
  text-decoration: none;
}

.vksub-name a:hover {
  text-decoration: underline;
}

.vksub-desc {
  font-size: 12px;
  color: #65676b;
  margin-top: 1px;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Индикатор — как зелёный "active"  */
.vksub-indicator {
  width: 10px;
  height: 10px;
  background: #31a24c;                /* зелёный онлайн */
  border: 2px solid #fff;
  border-radius: 50%;
  box-shadow: 0 1px 4px rgba(49,162,76,0.3);
  margin-left: 8px;
  flex-shrink: 0;
}

.vksub-item:hover .vksub-indicator {
  box-shadow: 0 0 6px rgba(49,162,76,0.5);
}

/* Пустой блок */
.vksub-empty {
  padding: 16px 12px;
  text-align: center;
  color: #65676b;
  font-size: 13px;
}

/* Анимация появления — мягкая, */
@keyframes fbFadeIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

.vksub-name a:hover { text-decoration: none; }

/* Адаптив — ещё компактнее на мобильных */
@media (max-width: 900px) {
  .vksub-block { margin: 8px 0; border-radius: 6px; }
  .vksub-head { padding: 7px 10px; font-size: 13px; }
  .vksub-avatar { width: 32px; height: 32px; margin-right: 8px; }
  .vksub-item { padding: 7px 10px; margin: 1px 3px; }
  .vksub-name { font-size: 12.5px; }
  .vksub-container { max-height: 180px; }
}
</style>

Мурчанн

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