Модуль Подарков как ВК для Ucoz
Дата: Среда, 24.12.2025, 20:08 | Сообщение # 1 |
|
Написал: Узнаваемый
Автор темы
Мурчанн
не в сети
Сообщений: 162
Продолжение создания шаблона ВКонтакте для 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
Вторая версия 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
Да, можно сделать окно с подробной информацией о том, кто отправил подарок: ник автора, отправитель и другие дополнительные сведения.
Признаюсь, не знаю почему, но глядя на звезды мне всегда хочется мечтать.