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

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

  • Страница 1 из 1
  • 1
История Репутации и Отзывы (без API) UcOz V 2.0
Дата: Воскресенье, 30.11.2025, 06:39 | Сообщение # 1 | | Написал: Начинающий
Автор темы
Мурчанн не в сети
        Сообщений:123
         Регистрация:20.10.2016

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

Парсер настроен на любой блог: укажите ссылку на нужную тему, и он автоматически будет подтягивать пользователей, которые оставляют комментарии в указанной теме. Так формируется список последних активных пользователей.



Логика работы следующая: устанавливается кнопка «Жалобы и предложения», доступ к теме возможен только через ваш профиль. Как только пользователь заходит и оставляет комментарий, он автоматически подтягивается парсером к форме комментариев. Для работы достаточно просто изменить ссылку на нужную тему.

Это полностью исходный код со всеми скриптами - без всяких плясок с бубнами у костра и прочих обёрток. Другими словами, если ты в теме, разберёшься легко, а для остальных это просто набор символов.



Код
<script src="https://bro.usite.pro/js/rep01.js"></script>
<div class="rep-do-list"><img src="/.s/img/wd/1/ajax.gif"></div>

<input type="hidden" class="rep-do-id" value="$_USER_ID$">
<input type="hidden" class="rep-do-group" value="$GROUP_ID$">

<div class="rep-rating-buttons">
<button class="rep-btn" data-val="2">Плюс</button>
<button class="rep-btn" data-val="0">Нейтрально</button>
<button class="rep-btn" data-val="1">Минус</button>

<!-- скрытые input для формы -->
<input type="radio" name="rep" value="2" id="rep-good" hidden>
<input type="radio" name="rep" value="0" id="rep-neutral" hidden>
<input type="radio" name="rep" value="1" id="rep-bad" hidden>
</div>

<style>
.rep-rating-buttons {
display: flex;
gap: 6px;

position: relative; /* чтобы можно было смещать */
top: 220px; /* смещение вверх */
left: 270px; /* смещение вправо */
}

.rep-btn {
width: 100px;
height: 20px;
border: 2px solid #ccc;
border-radius: 5px;
background-color: #fff;
color: #333;
font-weight: bold;
font-size: 10px; /* ← вот здесь задаём размер шрифта */
cursor: pointer;
transition: all 0.2s ease;
}

/* Наведение */
.rep-btn[data-val="2"]:hover {
background-color: #4caf50;
color: #fff;
border-color: #4caf50;
}

.rep-btn[data-val="0"]:hover {
background-color: #9e9e9e;
color: #fff;
border-color: #9e9e9e;
}

.rep-btn[data-val="1"]:hover {
background-color: #f44336;
color: #fff;
border-color: #f44336;
}

/* Выбранная кнопка фиксируется */
.rep-btn.selected[data-val="2"] {
background-color: #4caf50;
color: #fff;
border-color: #4caf50;
}

.rep-btn.selected[data-val="0"] {
background-color: #9e9e9e;
color: #fff;
border-color: #9e9e9e;
}

.rep-btn.selected[data-val="1"] {
background-color: #f44336;
color: #fff;
border-color: #f44336;
}

/* Сдвигаем форму вверх */
.rep-do-reason {
    margin-top: -30px; /* отрицательный отступ поднимает вверх */
    /* или альтернативно */
    /* transform: translateY(-50px); */
}

</style>

<script>
$(function(){
$('.rep-btn').click(function(){
// Снимаем выделение со всех кнопок
$('.rep-btn').removeClass('selected');

// Фиксируем выбранную кнопку
$(this).addClass('selected');

// Ставим значение в скрытый input
const val = $(this).data('val');
if(val == 2) $('#rep-good').prop('checked', true);
if(val == 0) $('#rep-neutral').prop('checked', true);
if(val == 1) $('#rep-bad').prop('checked', true);
});
});
</script>

<div class="feedback-form">

<!-- Кнопка смайлов -->
<textarea class="rep-do-reason" name="rtext" rows="3"
placeholder="Напиши свой отзыв..."></textarea>
<!-- Кнопка смайлов -->

<input class="btn-primary rep-do-go" type="submit" value="Добавить отзыв">

<button type="button" class="rep-do-add">Загрузить еще</button>

<!-- Панель смайлов -->
<div class="rep-smiley-panel" id="smilePanel"></div>

<style>

/* Родительский блок */
.parent-container {
position: relative; /* кнопка позиционируется внутри */
}

/* Сама кнопка */
.rep-smiley-btn {
position: absolute; /* привязка к родителю */
top: -15px; /* расстояние от верхнего края родителя */
right: 1px; /* расстояние от правого края */
z-index: 10; /* над другими элементами */
cursor: pointer;
font-size: 20px;
border: none;
background: transparent;
outline: none;
}

/* Кнопка смайлов */
.rep-smiley-btn {
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: 700;
width: 25px;
height: 25px;
border-radius: 8px;
border: 1px solid #488BFA;
background-color: #fff;
color: #488BFA;
cursor: pointer;
transition: all 0.3s ease;

/* ПОДЪЁМ КНОПКИ ВВЕРХ (без растяжения!) */
position: relative;
bottom: 35px; /* ↑ кнопка едет ВВЕРХ */

}

</style>

<button class="rep-smiley-btn" id="smileBtn">😎</button>

<!-- Родительский блок  -->
<div id="login-form" style="position: relative;">
<!-- сама форма входа -->

<!-- Контейнер друзей привязан под формой -->
<div class="ffc-wrapper">
<div class="ffc-container">
<div id="ffc-widget"></div>

<script>
$(function() {
const blogUrl = '/blog/murchann/2025-11-21-3';
const maxFriends = 6;
const styles = `
<style>
.ffc-wrapper {
position: absolute; /* привязка к родителю */
top: -400%; /* сразу под формой */
left: 0; /* при необходимости центрировать можно через left: 50% + transform */
transform: translateX(0);
width: 82%; /* можно ограничить ширину */

}

.ffc-container {
display: flex !important;
gap: 0px !important;
flex-wrap: wrap !important;
justify-content: center !important;
align-items: center !important;
padding: 8px !important;
}

/* карточки и аватар */
.ffc-card {
display: flex !important;
flex-direction: column !important;
align-items: center !important;
text-decoration: none !important;
color: inherit !important;
width: 85px !important;
margin: -8px !important;
transition: transform 0.3s ease !important;

}

.ffc-card:hover {
transform: scale(1.07);
}

.ffc-name {
font-family: 'Roboto', sans-serif !important;
font-weight: 500 !important;
font-size: 11px !important;
margin-top: 4px !important;
color: #111 !important;
text-align: center !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.2) !important;
}

.ffc-card img {
width: 40px !important;
height: 40px !important;
border-radius: 50% !important;
object-fit: cover !important;
border: 5px solid #fff !important;
outline: 2px solid #0a66c2 !important;
outline-offset: -9px !important;
box-shadow: 0 2px 8px rgba(0,0,0,0.2) !important;
transition: transform 0.3s ease, outline-color 0.3s ease, box-shadow 0.3s ease;
}

.ffc-card:hover img {
transform: scale(1.12);
outline-color: #3b8cf6;
box-shadow: 0 6px 15px rgba(0,0,0,0.35), 0 0 6px #3b8cf6;
}

/* адаптивность */
@media (max-width: 480px) {
.ffc-card {
width: 70px;
margin: 2px;
}

.ffc-card img {
width: 50px;
height: 50px;
}

.ffc-name {
font-size: 12px;
margin-top: 4px;
}
}
</style>

`;
$('head').append(styles);

/* Загрузка гостей как “друзей” */
function loadFriends() {
$.get(blogUrl, function(data) {
const tempDom = $('<div>').html(data);
const comments = tempDom.find('.comEnt').slice(0, maxFriends);

if (comments.length === 0) {
$('#ffc-widget').html('');
return;
}

/* Формируем HTML */
let html = '<div class="ffc-wrapper">';
html += '<div class="ffc-container">';

comments.each(function() {
const author = $(this).find('.uc-profile-link span').text() || 'Гость';
const avatar = $(this).find('.comm-card-avatar img').attr('src') || '/.s/src/profile/img/profile_photo_thumbnail.png';
const profileLink = $(this).find('.uc-profile-link').attr('href') || '#';

html += `
<a href="${profileLink}" target="_blank" class="ffc-card ffc-card">
<img src="${avatar}">
<div class="ffc-name" title="${author}">${author}</div>
</a>
`;
});

html += '</div></div>';
html += '</div>';

/* Полоска снизу отдельно */
html += `

`;

$('#ffc-widget').html(html);
});
}

loadFriends();
setInterval(loadFriends, 30000);
});
</script>

</div>
</div>
</div>

<!-- ========== Репутация: чистый вид + управляемые кнопки ========== -->
<div id="rep-widget">
<div class="rep-row">
<div class="rep-label">Репутация:</div>
<div class="rep-content">
<span class="rep-badge">
<a href="$_REP_READ_URL$" class="rep-link">$_REPUTATION$</a>
</span>
<?if($_REP_DO_URL$)?><span class="rep-small">
<a href="$_REP_DO_URL$" class="rep-edit">изменить</a>
</span>

<?endif?>
</div>
</div>

<div class="rep-controls" aria-hidden="false">
<?if($_REP_DO_URL$)?><a href="$_REP_DO_URL$" class="rep-btn rep-btn-left" title="Форма репутации">◀︎</a><?endif?>
<span class="rep-btn rep-btn-reset" title="Сброс">●</span>
<a href="$_REP_READ_URL$" class="rep-btn rep-btn-right" title="Список репутаций">▶︎</a>
</div>
</div>

<style>
/* Универсальные стили для репутации без фона блока */
#rep-widget { display:inline-block; padding:0; border:none; }

.rep-row { display:flex; align-items:center; gap:5px; }
.rep-label { font-weight:bold; font-size:14px; color:#222; }
.rep-content { display:flex; align-items:center; gap:6px; }
.rep-badge a.rep-link { padding:2px 6px; border-radius:4px; font-weight:bold; font-size:13px; background:#e5e5e5; color:#000; text-decoration:none; }
.rep-small a.rep-edit { font-size:11px; color:#444; text-decoration:underline; opacity:0.8; }

/* Контейнер кнопок слева */
.rep-controls { display:flex; justify-content:flex-start; align-items:center; gap:4px; margin-top:4px; }

/* Кнопки */
a.rep-btn, span.rep-btn {
display:inline-flex;
justify-content:center;
align-items:center;
border-radius:50%;
text-decoration:none;
user-select:none;
transition: transform 0.15s;
font-size:8px;
width:14px;
height:14px;
background:#555;
color:#fff;
}

a.rep-btn-left { background:#555; }
a.rep-btn-right { background:#555; }
span.rep-btn-reset { width:22px; background:#999; border-radius:8px; }

a.rep-btn:hover, span.rep-btn:hover { transform:scale(1.15); }
</style>

<script>
(function(){
const widget = document.getElementById('rep-widget');
if (!widget) return;

const badgeAnchors = widget.querySelectorAll('.rep-badge .rep-link');

// Окрас репутации
badgeAnchors.forEach(a => {
const raw = (a.textContent || '').trim();
const match = raw.match(/-?\d+/);
const v = match ? parseInt(match[0], 10) : 0;

a.textContent = v > 0 ? '+' + v : '' + v;

const badge = a.closest('.rep-badge');
if (!badge) return;

const gradeClasses = ['rep-1','rep-10','rep-50','rep-100','rep--1','rep--10','rep--50','rep--100','rep-poop','rep-0'];
gradeClasses.forEach(c => badge.classList.remove(c));

if (v >= 100) badge.classList.add('rep-100');
else if (v >= 50) badge.classList.add('rep-50');
else if (v >= 10) badge.classList.add('rep-10');
else if (v >= 1) badge.classList.add('rep-1');
else if (v <= -100) badge.classList.add('rep-poop');
else if (v <= -50) badge.classList.add('rep--50');
else if (v <= -10) badge.classList.add('rep--10');
else if (v <= -1) badge.classList.add('rep--1');
else badge.classList.add('rep-0');
});
})();
</script>

</div>

<script>
const smiles = document.querySelectorAll('.rep-smile');
smiles.forEach(smile => {
smile.addEventListener('click', () => {
// снимаем выделение с других
smiles.forEach(s => s.classList.remove('selected'));
// выделяем кликнутый
smile.classList.add('selected');
// ставим значение в скрытую радиокнопку
const val = smile.dataset.val;
const radio = document.querySelector(`input[name="rep"][value="${val}"]`);
if(radio) radio.checked = true;
});
});
</script>


Остальные стили остаются в первой теме, они, в принципе, не менялись.

Это дополнение к тому стилю - просто добавляйте нужные элементы избирательно, не обязательно всё подряд, только то, что действительно необходимо.

Код
.rep-do-list .prj-date {
    padding-left: 17px;
    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDE0IDc5LjE1Njc5NywgMjAxNC8wOC8yMC0wOTo1MzowMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MjlCQUI4OTZFQ0VGMTFFNEE2MDRBRjkwNDhBOUVDRkQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MjlCQUI4OTdFQ0VGMTFFNEE2MDRBRjkwNDhBOUVDRkQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowQTE0QzZGRkVDQkYxMUU0QTYwNEFGOTA0OEE5RUNGRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowQTE0QzcwMEVDQkYxMUU0QTYwNEFGOTA0OEE5RUNGRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PmLnSBYAAACBSURBVHjaYrSwc2dAAsZAbAHEU6H8UiDeB8RnYQpYgHg9EPNA+QJQHADlqwBxGBB/gPK/gjTwA7ETVEAWiNWAeC+UD7L+KhA/gfL3sTCggsdQDAM70eQZmJDYwVCMj82AbEMqEDMC8Vo8bBQNHkSwB7uTiAIgG1iBeDuR6lkBAgwAqRwaxBLXcoAAAAAASUVORK5CYII=) no-repeat 0;
    white-space: nowrap;
    display: inline-block;
}

/* Scoped styles — только внутри #rep-widget чтобы не ломать сайт */
#rep-widget { font-family: "Roboto", system-ui, -apple-system, "Segoe UI", "Helvetica Neue", Arial; display:inline-block; }

#rep-widget .rep-row {
  display:flex;
  align-items:center;
  gap:10px;
  padding:6px 8px;
  border-radius:8px;
  background: #fafafa;
  max-width: 420px;
  box-sizing: border-box;
}

/* label */
#rep-widget .rep-label {
  font-weight:600;
  font-size:14px;
  color:#222;
  margin-right:2px;
  flex: 0 0 auto;
}

/* content area */
#rep-widget .rep-content { display:flex; align-items:center; gap:8px; flex:1 1 auto; }

/* badge base */
#rep-widget .rep-badge { display:inline-block; }
#rep-widget .rep-badge .rep-link {
  display:inline-block;
  font-weight:700;
  font-size:14px;
  padding:4px 6px;
  border-radius:6px;
  text-decoration:none;
  color:inherit;
  min-width:26px;
  text-align:center;
  box-sizing:border-box;
  transition: box-shadow .18s ease, transform .12s ease;
  border:2px solid transparent;
}

/* edit link */
#rep-widget .rep-small .rep-edit {
  font-weight:600;
  font-size:12px;
  padding:4px 6px;
  border-radius:6px;
  text-decoration:none;
  color:#0a66c2;
  border:1px solid rgba(10,102,194,0.12);
  transition: background .15s ease, color .15s ease, transform .08s;
}
#rep-widget .rep-small .rep-edit:hover { background:#0a66c239; color:#063b6b; transform:translateY(-1px); }

/* Positive gradation (clearly different colors) */
#rep-widget .rep-1   .rep-link { background:#e8f8ee; color:#1f7a3b; border-color:#bfe8c6; }
#rep-widget .rep-10  .rep-link { background:#8fe59c; color:#063b12; border-color:#66c376; box-shadow:0 4px 12px rgba(46,204,113,0.12); }
#rep-widget .rep-50  .rep-link { background:#38c172; color:#001; border-color:#2aa65a; box-shadow:0 6px 18px rgba(56,193,114,0.14); }
#rep-widget .rep-100 .rep-link { background:linear-gradient(135deg,#ffd966,#ffb300); color:#2b2200; border-color:#d4a81a; box-shadow:0 8px 20px rgba(212,168,26,0.18); }

/* Negative gradation (clearly different) */
#rep-widget .rep--1   .rep-link { background:#fff0f0; color:#9b2b2b; border-color:#f3c1c1; }
#rep-widget .rep--10  .rep-link { background:#ffb6b6; color:#7a0606; border-color:#ff8b8b; box-shadow:0 6px 14px rgba(220,53,69,0.12); }
#rep-widget .rep--50  .rep-link { background:#e74c3c; color:#fff; border-color:#c4332b; box-shadow:0 8px 18px rgba(231,76,60,0.18); }
#rep-widget .rep--100 .rep-link { background:#3a0d0d; color:#fff; border-color:#2b0707; box-shadow:0 8px 22px rgba(0,0,0,0.45); }

/* Extremely negative — brown "poop" with tiny flies (subtle) */
#rep-widget .rep-poop .rep-link {
  background:#5b3d26;
  color:#f3e6d8;
  border-color:#4b2f1e;
  box-shadow: inset 0 -4px 8px rgba(0,0,0,0.15);
  position:relative;
}
#rep-widget .rep-poop .rep-link::after {
  content:"??";
  font-size:12px;
  margin-left:6px;
  display:inline-block;
  opacity:0.8;
  transform:translateY(-1px);
  animation: flysmall .9s ease-in-out infinite alternate;
}
@keyframes flysmall { from{transform:translateY(-1px) rotate(0deg);} to{transform:translateY(-6px) rotate(20deg);} }

/* Neutral */
#rep-widget .rep-0 .rep-link { background:#eef3f7; color:#334; border-color:#d5dee6; }

/* Controls (buttons) */
#rep-widget .rep-controls { margin-top:8px; display:flex; gap:8px; align-items:center; }
#rep-widget .rep-btn {
  -webkit-appearance:none; appearance:none;
  border:2px solid #0a66c2;
  background:#fff;
  color:#0a66c2;
  padding:6px 10px;
  border-radius:8px;
  font-weight:700;
  cursor:pointer;
  transition: background .15s ease, color .15s ease, transform .12s ease, box-shadow .12s;
  box-shadow: 0 2px 6px rgba(10,102,194,0.08);
}
#rep-widget .rep-btn:hover { background:#0a66c2; color:#fff; transform:translateY(-2px); box-shadow:0 8px 24px rgba(10,102,194,0.18); }
#rep-widget .rep-btn:active { transform:translateY(0); box-shadow:0 4px 12px rgba(10,102,194,0.12); }
#rep-widget .rep-btn.rep-btn-reset { border-color:#777; color:#333; background:#fff; }

/* Фиксированный размер смайлов внутри комментариев */
.rep-do-list .answer .text .rep-smile {
width: 26px !important;
height: 26px !important;
object-fit: contain; /* сохраняет пропорции */
vertical-align: middle; /* чтобы по центру текста выравнивалось */
}

/* Настройки сдвига и позиции */
:root {
--photos-horizontal-shift: 120px; /* вправо = +, влево = - */
--photos-vertical-shift: 30px; /* вверх = -, вниз = + */
--photo-size: 100px; /* размер фото */
--photo-border-radius: 0px; /* скругление */
--photo-border-hover: #000; /* цвет рамки при наведении */
}

/* Контейнер профиля */
.profile-header {
display: flex;
align-items: flex-start;
justify-content: flex-start; /* ник слева */
position: relative; /* чтобы фото были абсолютными относительно этого блока */
padding-top: 10px;
}

/* Сетка фото — фиксированная справа и сверху окна */
.profile-photo-grid {
display: flex;
gap: 10px;
flex-wrap: wrap;

position: fixed; /* фиксируем относительно окна */
top: 40px; /* расстояние от верхнего края окна */
right: 20px; /* расстояние от правого края окна */
z-index: 999; /* всегда поверх */
}

/* Фото карточки */
.photo-card img {
width: var(--photo-size);
height: var(--photo-size);
object-fit: cover;
border-radius: 8px;
border: 1px solid #0a66c2;
transition: all 0.3s ease;
cursor: pointer;
}

/* Эффекты при наведении */
.photo-card img:hover {
transform: scale(1.1);
filter: brightness(0.8);
box-shadow: 0 6px 18px rgba(0,0,0,0.35);
}


Пока идёт разработка, я параллельно занимаюсь другими проектами, и могу докидывать стили в запарке , не относящиеся напрямую к этой задаче. Возможны также дубли - моя специфика , когда я сразу работаю над несколькими задачами одновременно это обычное дело. 2

История Репутации и Отзывы (без API) UcOz JS

Мурчанн

Признаюсь, не знаю почему, но глядя на звезды мне всегда хочется мечтать.
Дата: Воскресенье, 30.11.2025, 07:13 | Сообщение # 2 | | Написал: Начинающий
Автор темы
Мурчанн не в сети
        Сообщений:123
         Регистрация:20.10.2016

Мурчанн

Признаюсь, не знаю почему, но глядя на звезды мне всегда хочется мечтать.
Дата: Воскресенье, 30.11.2025, 20:46 | Сообщение # 3 | | Написал: Начинающий
Автор темы
Мурчанн не в сети
        Сообщений:123
         Регистрация:20.10.2016

Обязательно подключите 12

Код
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

Мурчанн

Признаюсь, не знаю почему, но глядя на звезды мне всегда хочется мечтать.
Дата: Среда, 03.12.2025, 00:53 | Сообщение # 4 | | Написал: Начинающий
Автор темы
Мурчанн не в сети
        Сообщений:123
         Регистрация:20.10.2016

Пример того, как обычно выглядит стандартная шкала замечаний на Ucoz, а также пример того, как можно создать свою собственную шкалу замечаний с помощью JavaScript.



Пример того как можно создать свою шкалу замечаний.



JS

Код
document.addEventListener('DOMContentLoaded', function () {
  const ratingImgs = Array.from(document.querySelectorAll('.profile-row-content img[src*="/img/fr/w"]'));
  if (!ratingImgs.length) return;

  ratingImgs.forEach(img => {
    const row = img.closest('.profile-row-content');
    if (!row) return;

    // Берём процент
    const percentAnchor = row.querySelector('.banPercent');
    let percent = 0;
    if (percentAnchor) {
      const match = percentAnchor.textContent.match(/\d{1,3}/);
      if (match) percent = Math.min(100, Math.max(0, parseInt(match[0], 10)));
    }

    // Прячем оригинальную системную полоску Ucoz
    img.style.display = 'none';

    // Подменяем wm.gif на прозрачный 1×1 и убираем размер
    const iconWM = row.querySelector('img[src*="wm.gif"]');
    if (iconWM) {
      iconWM.src = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';
      iconWM.style.width = '1px';
      iconWM.style.height = '1px';
      iconWM.style.padding = '0';
      iconWM.style.margin = '0';
      iconWM.style.border = '0';
      iconWM.style.opacity = '0';
      iconWM.style.display = 'inline-block';
    }

    // Создаём обёртку для шкалы + процента
    const wrapper = document.createElement('div');
    wrapper.className = 'ban-bar-wrapper';
    wrapper.style.display = 'inline-flex';
    wrapper.style.alignItems = 'center';
    wrapper.style.gap = '6px';

    // Кнопки + −
    const btnPlus = document.createElement('button');
    const btnMinus = document.createElement('button');

    [btnPlus, btnMinus].forEach(btn => {
      btn.type = 'button';
      btn.style.width = '22px';
      btn.style.height = '22px';
      btn.style.background = '#0a9fff';
      btn.style.border = 'none';
      btn.style.borderRadius = '4px';
      btn.style.color = '#fff';
      btn.style.fontWeight = '900';
      btn.style.fontSize = '14px';
      btn.style.cursor = 'pointer';
      btn.style.boxShadow = '0 2px 5px rgba(10,159,255,0.3)';
      btn.style.transition = '0.15s';
      btn.onmouseover = () => btn.style.background = '#0077dd';
      btn.onmouseout = () => btn.style.background = '#0a9fff';
      btn.onmousedown = () => btn.style.transform = 'scale(0.9)';
      btn.onmouseup = () => btn.style.transform = 'scale(1)';
    });

    btnPlus.textContent = '+';
    btnMinus.textContent = '−';

    // Шкала
    const bar = document.createElement('div');
    bar.style.position = 'relative';
    bar.style.width = '340px';
    bar.style.height = '10px';
    bar.style.background = '#fff';
    bar.style.border = '1px solid #ddd';
    bar.style.borderRadius = '6px';
    bar.style.overflow = 'hidden';
    bar.style.boxShadow = 'inset 0 0 3px rgba(0,0,0,0.1)';

    // Деления линейки как на линейке
    const ruler = document.createElement('div');
    ruler.style.position = 'absolute';
    ruler.style.top = '0';
    ruler.style.left = '0';
    ruler.style.width = '100%';
    ruler.style.height = '100%';
    ruler.style.backgroundImage = 'repeating-linear-gradient(90deg, rgba(0,0,0,0.25) 0 2px, transparent 2px 68px)';
    ruler.style.pointerEvents = 'none';

    // Заливка процента
    const fill = document.createElement('div');
    fill.style.position = 'absolute';
    fill.style.top = '0';
    fill.style.left = '0';
    fill.style.height = '100%';
    fill.style.width = percent + '%';
    fill.style.borderRadius = '6px';
    fill.style.transition = 'width 0.35s ease, background 0.35s ease';

    // Цвет градиентом только для 20%
    function updateFill(p) {
      percentDisplay.textContent = p + '%';
      fill.style.width = p + '%';
      if (p <= 20) fill.style.background = 'linear-gradient(135deg, #ffd966, #ffb300)';
      else if (p <= 40) fill.style.background = '#ff9900';
      else if (p <= 60) fill.style.background = '#ff6600';
      else if (p <= 80) fill.style.background = '#ff3300';
      else if (p <= 100) fill.style.background = '#cc0000';
    }

    bar.appendChild(ruler);
    bar.appendChild(fill);

    // Контейнер для процента (всегда справа)
    const percentDisplay = percentAnchor && percentAnchor.cloneNode(true) || document.createElement('div');
    percentDisplay.style.marginLeft = '8px';
    percentDisplay.style.fontSize = '13px';
    percentDisplay.style.fontWeight = '700';
    percentDisplay.style.color = '#fff';
    percentDisplay.style.background = '#0a9fff';
    percentDisplay.style.padding = '2px 6px';
    percentDisplay.style.borderRadius = '6px';

    // Собираем
    wrapper.appendChild(btnMinus);
    wrapper.appendChild(bar);
    wrapper.appendChild(btnPlus);
    wrapper.appendChild(percentDisplay);

    // Вставляем шкалу после самого процента в профиле
    if(percentAnchor){
     percentAnchor.style.display='none'; // ← чтобы не дублировался старый %
     row.insertBefore(wrapper, percentAnchor.nextSibling);
    } else {
     row.appendChild(wrapper);
    }

    // Навешиваем клики + −
    btnPlus.onclick = e => {
      e.preventDefault();
      percent = Math.min(100, percent + 5);
      updateFill(percent);
    };

    btnMinus.onclick = e => {
      e.preventDefault();
      percent = Math.max(0, percent - 5);
      updateFill(percent);
    };

    updateFill(percent);
  });
});


На uCoz можно создать отдельный глобальный блок, который будет отвечать только за шкалу замечаний, и потом подключать его в любой модуль: профиль, форум, каталог файлов, новости и т.д.

Это мой блок .

Код
<div id="" style="fixed-ban-block ">

<div class="profile-row">

<div class="profile-row-content">

<a class="banPercent" title="Смотреть историю замечаний" href="$_BAN_READ_URL$">
$_BAN_PERCENT$%
</a>

<img src="http://s28.ucoz.net/img/fr/w$_BAN_RATING$.gif"/>

</div>
</div>

</div>

<script src="https://bro.usite.pro/js/ban.js"></script>

<?if($_BAN_DO_URL$)?>
<a href="$_BAN_DO_URL$" style="position:absolute; top:1px; left:460px;">
<img title="Изменить" src="https://www.kolobok.us/smiles/icq/bomb.gif"/>
</a>
<?endif?>


Для размещения и управления

Код
<!-- Бан -->
<div class="profile-section-content" style="position: relative;">
<div id="ban-anchor" style="position: absolute; top: -15px; right: 42px;">
$GLOBAL_BAN$
</div>
</div>
<!-- Бан -->


Претензии

Код
<div class="profile-section-content" style="position: relative;">
<div id="ban-anchor" style="position: absolute; top: -14px; right: 510px;">
Претензии:
</div>
</div>


Делайте так, как считаете нужным - полностью на ваше усмотрение. 2

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

Мурчанн

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