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

1
Админ
Постов: 162
2
Элита
Постов: 45
3
VIP
Постов: 35
4
Проверенные
Постов: 31
5
Проверенные
Постов: 30
6
Пользователи
Постов: 27
7
VIP
Постов: 26
8
Пользователи
Постов: 24

  • Страница 1 из 1
  • 1
Модуль Подарков как ВК для Ucoz
Дата: Среда, 24.12.2025, 20:08 | Сообщение # 1 | | Написал: Узнаваемый
Автор темы
Мурчанн не в сети
        Сообщений:162
         Регистрация:20.10.2016

Продолжение создания шаблона ВКонтакте для Ucoz

На этот раз я реализовал блок подарков, который выводится прямо на главную страницу сайта. При работе с этим модулем возникли сложности с порядком отображения подарков.

Дело в том, что на платформе Ucoz подарки разделены на категории , например, «Знаки отличия» или «Животные». В зависимости от категории формируется отдельный внутренний список подарков, и написать скрипт, который бы корректно выводил последний подарок, оказалось невозможно.

Чтобы сохранить правильный порядок отображения, лучше объединить все подарки в одной категории. В нашем случае я именно так и сделал. Это решение более оптимальное, так как позволило корректно управлять выводом подарков на странице и избежать путаницы с внутренними списками Ucoz.



Скрипт, который выводит блок подарков, работает по простому принципу: создаём глобальный блок на странице и помещаем туда модуль подарков. Данный модуль позволяет:

1. Отображать последние подарки пользователя;

2. Центрировать подарки на странице;

3. При клике на счётчик открывать всплывающее окно со списком всех подарков;

4. корректно обрабатывать количество подарков и их порядок.

Ниже представлен сам скрипт для блока подарков, который можно встроить на страницу:

(далее вставляется текущий рабочий скрипт)

Код
<!-- ======= Блок подарков  ======= -->
<div class="gifts-block">
<div class="gifts-header">Подарки</div>
<div class="gifts-footer" id="gifts-count">Загрузка…</div>
<div class="gifts-container" id="gifts-container"></div>
</div>

<style>
.gifts-block {
background: #fff;
border: 1px solid #d1d5da;
font-family: Tahoma, Arial, sans-serif;
font-size: 13px;
color: #000;
max-width: 600px;
}

.gifts-header {
background: #f0f2f5;
padding: 6px 8px;
border-bottom: 1px solid #d1d5da;
color: #45688e;
font-weight: bold;
}

.gifts-footer {
background: #f7f7f7;
border-top: 1px solid #d1d5da;
padding: 5px 8px;
color: #666;
}

.gifts-container {
display: flex;
gap: 10px;
padding: 10px 8px;
flex-direction: row-reverse; /* последние подарки справа налево */
}

.gift-card {
width: 140px;
text-align: center;
position: relative;
cursor: pointer;
}

.gift-card img {
width: 78px;
height: 78px;
border-radius: 50%;
object-fit: cover;
margin: 0 auto;
transition: .25s ease;
}

.gift-card::after {
content: '';
position: absolute;
inset: 0;
border-radius: 15%;
background: rgba(0,0,0,.25);
opacity: 0;
transition: .25s ease;
}

.gift-card:hover::after {
opacity: 0.1;
}
</style>

<script>
(function(){

const container = document.getElementById('gifts-container');
const counter = document.getElementById('gifts-count');
const userId = <?$JSENCODE$($USER_ID$)?>;

let allGifts = [];

function loadGifts(){

   fetch(`/index/54-${userId}-`)
     .then(r => r.text())
     .then(text => {

       const xml = new DOMParser().parseFromString(text, 'application/xml');
       const cmd = xml.querySelector('cmd[p="content"]');
       if(!cmd){
         counter.textContent = 'Подарки недоступны';
         return;
       }

       const temp = document.createElement('div');
       temp.innerHTML = cmd.textContent;

       const tds = Array.from(temp.querySelectorAll('td[onclick*="_uWnd.reload"]'));
       if(!tds.length){
         counter.textContent = 'Подарков нет';
         container.innerHTML = '';
         return;
       }

       let total = 0;
       allGifts = [];
       tds.forEach(td => {
         const img = td.querySelector('img');
         if(!img) return;
         const b = td.querySelector('b');
         const count = b ? parseInt(b.textContent) || 1 : 1;
         total += count;
         for(let i=0;i<count;i++){
           allGifts.push({img: img.src, onclick: td.getAttribute('onclick')});
         }
       });

       counter.textContent = total + ' подарков';
       container.innerHTML = '';

       // показываем первые 3, центрируем
       container.style.display = 'flex';
       container.style.justifyContent = 'center';
       container.style.alignItems = 'center';
       container.style.gap = '10px';

       allGifts.slice(0,3).forEach(g => {
         const div = document.createElement('div');
         div.className = 'gift-card';
         div.innerHTML = `<img src="${g.img}" alt="Подарок">`;
         div.onclick = () => { if(typeof _uWnd !== 'undefined') eval(g.onclick); };
         container.appendChild(div);
       });

     })
     .catch(err => {
       console.error(err);
       counter.textContent = 'Ошибка загрузки';
     });
}

function showPopup(){
   if(!allGifts.length) return;

   const overlay = document.createElement('div');
   overlay.style = `
     position: fixed;
     inset: 0;
     background: rgba(0,0,0,0.5);
     display: flex;
     justify-content: center;
     align-items: center;
     z-index: 9999;
   `;

   const popup = document.createElement('div');
   popup.style = `
     position: relative;
     background: #fff;
     padding: 20px;
     border-radius: 8px;
     width: 700px;
     max-height: 80vh;
     overflow-y: auto;
     display: flex;
     flex-wrap: wrap;
     justify-content: center; /* центрируем подарки */
     gap: 10px;
   `;

   // крестик закрытия
   const closeBtn = document.createElement('div');
   closeBtn.innerHTML = '×';
   closeBtn.style = `
     position: absolute;
     top: 10px;
     right: 15px;
     font-size: 24px;
     font-weight: bold;
     cursor: pointer;
     color: #333;
   `;
   closeBtn.onclick = () => overlay.remove();
   popup.appendChild(closeBtn);

   allGifts.forEach(g => {
     const div = document.createElement('div');
     div.className = 'gift-card';
     div.style.cursor = 'pointer';
     div.innerHTML = `<img src="${g.img}" style="width:140px;height:140px;border-radius:50%" alt="Подарок">`;
     div.onclick = () => { if(typeof _uWnd !== 'undefined') eval(g.onclick); };
     popup.appendChild(div);
   });

   overlay.appendChild(popup);
   document.body.appendChild(overlay);

   // закрытие по клику на фон
   overlay.addEventListener('click', e => {
     if(e.target === overlay) overlay.remove();
   });
}

counter.style.cursor = 'pointer';
counter.title = 'Нажмите, чтобы увидеть все подарки';
counter.addEventListener('click', showPopup);

loadGifts();
setInterval(loadGifts, 30000);

})();
</script>


Мурчанн

Признаюсь, не знаю почему, но глядя на звезды мне всегда хочется мечтать.
Дата: Четверг, 25.12.2025, 15:45 | Сообщение # 2 | | Написал: Узнаваемый
Автор темы
Мурчанн не в сети
        Сообщений:162
         Регистрация:20.10.2016

Вторая версия V2

Код
<!-- ======= Блок подарков ======= -->
<div class="gifts-block">
<div class="gifts-header">Подарки</div>
<div class="gifts-footer" id="gifts-count">Загрузка…</div>
<div class="gifts-container" id="gifts-container"></div>
</div>

<style>
.gifts-block {
background: #fff;
border: 1px solid #d1d5da;
font-family: Tahoma, Arial, sans-serif;
font-size: 13px;
color: #000;
max-width: 600px;
}

.gifts-header {
background: #f0f2f5;
padding: 6px 8px;
border-bottom: 1px solid #d1d5da;
color: #45688e;
font-weight: bold;
}

.gifts-footer {
background: #f7f7f7;
border-top: 1px solid #d1d5da;
padding: 5px 8px;
color: #666;
}

.gifts-container {
display: flex;
gap: 10px;
padding: 10px 8px;
flex-direction: row-reverse; /* последние подарки справа налево */
}

.gift-card {
width: 140px;
text-align: center;
position: relative;
cursor: pointer;
}

.gift-card img {
width: 88px;
height: 88px;
border-radius: 0%;
object-fit: cover;
margin: 0 auto;
transition: .25s ease;
}

.gift-card::after {
content: '';
position: absolute;
inset: 0;
border-radius: 5%;
background: rgba(0,0,0,.25);
opacity: 0;
transition: .25s ease;
}

.gift-card:hover::after {
opacity: 0.1;
}
</style>

<script>
(function(){

const container = document.getElementById('gifts-container');
const counter = document.getElementById('gifts-count');
const userId = <?$JSENCODE$($USER_ID$)?>;

let allGifts = [];

function loadGifts(){

fetch(`/index/54-${userId}-`)
.then(r => r.text())
.then(text => {

const xml = new DOMParser().parseFromString(text, 'application/xml');
const cmd = xml.querySelector('cmd[p="content"]');
if(!cmd){
counter.textContent = 'Подарки недоступны';
return;
}

const temp = document.createElement('div');
temp.innerHTML = cmd.textContent;

const tds = Array.from(temp.querySelectorAll('td[onclick*="_uWnd.reload"]'));
if(!tds.length){
counter.textContent = 'Подарков нет';
container.innerHTML = '';
return;
}

let total = 0;
allGifts = [];
tds.forEach(td => {
const img = td.querySelector('img');
if(!img) return;
const b = td.querySelector('b');
const count = b ? parseInt(b.textContent) || 1 : 1;
total += count;
for(let i=0;i<count;i++){
allGifts.push({img: img.src, onclick: td.getAttribute('onclick')});
}
});

counter.textContent = total + ' подарков';
container.innerHTML = '';

// показываем первые 3, центрируем
container.style.display = 'flex';
container.style.justifyContent = 'center';
container.style.alignItems = 'center';
container.style.gap = '10px';

allGifts.slice(0,3).forEach(g => {
const div = document.createElement('div');
div.className = 'gift-card';
div.innerHTML = `<img src="${g.img}" alt="Подарок">`;
div.onclick = () => { if(typeof _uWnd !== 'undefined') eval(g.onclick); };
container.appendChild(div);
});

})
.catch(err => {
console.error(err);
counter.textContent = 'Ошибка загрузки';
});
}

function showPopup(){
if(!allGifts.length) return;

const overlay = document.createElement('div');
overlay.style = `
position: fixed;
inset: 0;
background: rgba(0,0,0,0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
`;

const popup = document.createElement('div');
popup.style = `
position: relative;
background: #fff;
padding: 20px;
border-radius: 8px;
width: 700px;
max-height: 80vh;
overflow-y: auto;
display: flex;
flex-wrap: wrap;
justify-content: center; /* центрируем подарки */
gap: 10px;
`;

// крестик закрытия
const closeBtn = document.createElement('div');
closeBtn.innerHTML = '×';
closeBtn.style = `
position: absolute;
top: 10px;
right: 15px;
font-size: 24px;
font-weight: bold;
cursor: pointer;
color: #333;
`;
closeBtn.onclick = () => overlay.remove();
popup.appendChild(closeBtn);

allGifts.forEach(g => {
const div = document.createElement('div');
div.className = 'gift-card';
div.style.cursor = 'pointer';
div.innerHTML = `<img src="${g.img}" style="width:140px;height:140px;border-radius:0%" alt="Подарок">`;
div.onclick = () => { if(typeof _uWnd !== 'undefined') eval(g.onclick); };
popup.appendChild(div);
});

overlay.appendChild(popup);
document.body.appendChild(overlay);

// закрытие по клику на фон
overlay.addEventListener('click', e => {
if(e.target === overlay) overlay.remove();
});
}

counter.style.cursor = 'pointer';
counter.title = 'Нажмите, чтобы увидеть все подарки';
counter.addEventListener('click', showPopup);

loadGifts();
setInterval(loadGifts, 30000);

})();
</script>


Мурчанн

Признаюсь, не знаю почему, но глядя на звезды мне всегда хочется мечтать.
Дата: Четверг, 25.12.2025, 15:50 | Сообщение # 3 | | Написал: Узнаваемый
Автор темы
Мурчанн не в сети
        Сообщений:162
         Регистрация:20.10.2016

Да, можно сделать окно с подробной информацией о том, кто отправил подарок: ник автора, отправитель и другие дополнительные сведения.

Мурчанн

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