Merlin777
Есть такое выражение: "В погоне за улучшениями есть риск ухудшить то, что уже и так хорошо."
Изменение, которое внесли ChatGPT и ваш "джун" ("теперь ошибки при отсутствии интернета, обрыве соединения и т.п. не выводятся пользователям на страницу, а пишутся в консоль браузера") является вредным и неразумным. Большинство пользователей не в курсе о существовании консоли браузера и как та открывается. Консоль больше нужна разработчикам, чем пользователям, в скрипте нет отладочной информации. Вывод ошибок, связанный с отсутствием интернета, обрывом соединения и подобного ChatGPT связал с недоступностью API, что логично, но неверно интерпретировано. Пользователь, после обновления страницы, и сам будет видеть, что у него нет соединения с интернетом, в отличие от вероятных проблем с недоступностью API, о чем пользователь может быть не в курсе, ожидая момент, когда загрузится список тем. Всю отладочную информацию я специально убрал из скрипта для облегчения кода, сделав вывод ошибки во встроенный в сервис jGrowl (для админов), а в случае каких-либо проблем с jGrowl или jQuery, вывод ошибок для всех дублируется в блок вывода списка тем. А так вы лишили своих (и чужих) пользователей информации о возможных ошибках.
Я добавил "костыль" сервисного API в виде увеличения лимита по той причине, что не знаю как одним запросом вывести только выделенные темы (а лучше одним запросом ‒ сначала выделенные, а за ними все остальные). Если в нашем API такое возможно, то ребята подскажут как это сделать. Насколько сильно увеличится нагрузка при увеличении лимита, сказать сложно, но это явно не в пользу оптимизации. Сейчас запрос работает таким образом: он отсортировывает темы текущего форумИд по дате последнего сообщения по убыванию. Затем в процесс впрягается скрипт, вытягивая сначала выделенные темы (sticky: "1"), а затем все остальные. Есть большая вероятность, что при одновременном накоплении тем в разделе в количестве более 100 штук, одна или несколько выделенных тем, созданных в далеком прошлом, могут выпасть из списка до тех пор, пока в них не появится новое сообщение. Выделенные темы могут висеть закрытыми годами (такие темы являются правилами разделов, они созданы давно и закрыты от написания ответов). А вот обычные темы в разделе копятся. С увеличением лимита мы лишь временно купировали возникновение ошибки. Именно поэтому необходимо поработать с изменением запроса, если это возможно. В ином случае придется вновь возвращаться к парсингу.
У параметра sort_by нет параметра limit, оба параметра взаимосвязаны методами их использования.
Верно отметил Alex_63 про глобальные переменные. Я переписывал код по образу кода Fover, и уже после опубликования скрипта возникла та же мысль за переменную count ‒ из-за её значимого названия она много где может использоваться, однако я не стал её переименовывать, потому как за продолжительное время существования скрипта ни у кого не возникло проблем (но это не точно). Лучшим решением в данном случае будет сгруппировать все параметры в одном объекте, это позволит вынести логику скрипта в файл, а параметры настройки оставить рядом. Тогда переменные не пересекутся с другими скриптами, соответственно от использования анонимной функции можно отказаться, и наш код дозволяется использовать как в файле с отдельным выносом настроек, так и совместно, не пряча настройки скрипта в глубине.
Рекомендую также обновить стиль скрипта: ещё в прошлый период (через 2 дня после публикации) были внесены поправки для обеспечения корректного отображения на портативных устройствах.
Частично использовал логику вашего кода с кэшированием в 10 минут.
В случае отсутствия настроек скрипта добавил в логику стандартные значения (count = 10, useSession = 0, selectAct = 'click').
Обновлённый скрипт
Код:<!-- Первые N тем в описании форума (новая версия) -->
<style>
.topicslist {
position: absolute;
background-color: #fff;
border: 1px solid rgba(0, 0, 0, .35);
margin-top: 5px;
padding: 10px;
box-shadow: 0 4px 4px -2px rgba(0, 0, 0, .35);
border-radius: 3px;
max-width: 90vw;
z-index: 110;
.sticky a {
font-weight: bold;
color: #f00; /* Цвет для выделенных тем */
}
.closed a {
color: #a9a9a9; /* Цвет для закрытых тем */
}
}
.clickt {
cursor: pointer;
user-select: none;
}
</style>
<script>
const firstNtopics = {
count: 10, // Максимальное количество выводимых тем форума
useSession: 1, // 1 - включить sessionStorage, 0 - выключить
selectAct: 'click' // Вариант показа блока: 'click' (нажатие по символу рядом с названием темы) или 'hover' (наведение курсора на название темы)
};
</script>
<script>
function loadTopics(t,s){var e=Date.now();if(firstNtopics.useSession&&sessionStorage.getItem(s)){var i=JSON.parse(sessionStorage.getItem(s));e-i.timestamp<6e5?(t.find("ul").empty(),i.data.forEach(function(s){t.find("ul").append('<li class="'+s.class+'"><a href="'+s.url+'">'+s.subject+"</a></li>")})):sessionStorage.removeItem(s)}else $.getJSON("/api.php?method=topic.get&forum_id="+s+"&sort_by=last_post&sort_dir=desc&limit=100",function(i){if(t.find("ul").empty(),i&&i.response&&i.response.length>0){i.response.forEach(function(t){t.sticky=parseInt(t.sticky,10),t.closed=parseInt(t.closed,10)});var o=i.response.filter(function(t){return 1===t.sticky}).sort(function(t,s){return s.last_post_date-t.last_post_date}),c=i.response.filter(function(t){return 1!==t.sticky}).sort(function(t,s){return s.last_post_date-t.last_post_date}),l=o.concat(c).slice(0,firstNtopics.count).map(function(t){var s="";return 1===t.sticky&&(s+="sticky "),1===t.closed&&(s+="closed"),{subject:t.subject,url:"/viewtopic.php?id="+t.id,class:s.trim(),last_post_date:t.last_post_date}});l.forEach(function(s){t.find("ul").append('<li class="'+s.class+'"><a href="'+s.url+'">'+s.subject+"</a></li>")}),firstNtopics.useSession&&sessionStorage.setItem(s,JSON.stringify({data:l,timestamp:e}))}else t.find("ul").append("<li>В этом форуме нет тем.</li>")}).fail(function(s,e,i){t.find("ul").empty(),t.find("ul").append("<li>Ошибка при загрузке данных."+(1!==GroupID?"<br>Обратитесь к администратору форума.":"")+"</li>"),1===GroupID&&$.jGrowl('Произошла ошибка в скрипте Первые N тем в описании форума. Пожалуйста, обратитесь на форум технической поддержки. При обращении укажите ссылку на ваш форум.<br>Код ошибки: "'+i+'"',{sticky:!0})})}function showTopics(t){var s=t.parents("tr").attr("id").match(/\d+/)[0],e=t.closest("tr").find(".topicslist");currentForumId===s&&e.length||($(".topicslist").remove(),t.closest("tr").find("h3").after('<div class="topicslist"><ul><li>Загружаю список тем...</li></ul></div>'),loadTopics(t.closest("tr").find(".topicslist"),s),currentForumId=s,"hover"===firstNtopics.selectAct&&resetCloseTimeout(t.closest("tr").find(".topicslist")))}function resetCloseTimeout(t){clearTimeout(closeTimeout),closeTimeout=setTimeout(function(){t.remove(),currentForumId=null},2e3)}"undefined"==typeof firstNtopics&&(window.firstNtopics={count:10,useSession:0}),currentForumId=null,closeTimeout=null,"hover"===firstNtopics.selectAct?($(".tclcon h3 a").on("mouseenter",function(t){currentForumId!==$(this).parents("tr").attr("id").match(/\d+/)[0]&&showTopics($(this))}),$(document).on("mouseenter",".topicslist, .tclcon h3 a",function(){clearTimeout(closeTimeout)}),$(document).on("mouseleave",".topicslist, .tclcon h3 a",function(){resetCloseTimeout($(".topicslist"))})):($(".tclcon h3 a").each(function(){$(this).after(' <span class="clickt" title="Показать список тем этого форума">></span>')}),$(".clickt").on("click",function(t){t.stopPropagation();var s=$(this).closest("tr").attr("id").match(/\d+/)[0],e=$(this).closest("tr").find(".topicslist");currentForumId===s&&e.length?(e.remove(),currentForumId=null):showTopics($(this))})),$(document).click(function(t){$(t.target).closest(".topicslist").length||$(t.target).closest(".clickt").length||($(".topicslist").remove(),currentForumId=null)})
</script>
Обновил скрипт в теме Скрипты от пользователей 3
Отредактировано Reysler (Пт, 13 Сен 2024 11:15:19)