Бесконечная загрузка сообщений чата при прокрутке к вершине прокручиваемого элемента
Я пытаюсь загрузить сообщения чата, когда пользователь прокручивает страницу до верхней части div (div прокручивается, поэтому контекстом является не окно, а div). Также при загрузке страницы div автоматически прокручивается к низу. Я делаю это на django, и при выполнении этого кода путевая точка срабатывает, когда пользователь прокручивает страницу до низа, но div, который должен срабатывать (id=trigger-load), находится выше области просмотра. Я пробовал добавить таймаут для инициализации infinite_chat, но это тоже не помогло. Вот код:
class ChatDetail(LoginRequiredMixin, generic.ListView):
login_url = reverse_lazy('login')
model = Message
paginate_by = 20
context_object_name = 'messages'
template_name = 'index.html'
Html:
```
<div class="overflow-y-scroll px-5 pt-5 flex-1 infinite-container-chat" id="chat-content">
{% if page_obj.has_next %}
{% include 'partials/common/loader.html' %}
{% endif %}
<div class="" id="trigger-load"></div>
{% include 'partials/friend_hidden_message.html' %}
{% include 'partials/user_hidden_message.html' %}
{% for message in messages reversed %}
{% if forloop.first %}
<div class="infinite-item">
{% if user.id == message.user.id %}
{% include 'partials/user_message.html' %}
{% else %}
{% include 'partials/friend_message.html' %}
{% endif %}
</div>
{% else %}
<div class="infinite-item">
{% if user.id == message.user.id %}
{% include 'partials/user_message.html' %}
{% else %}
{% include 'partials/friend_message.html' %}
{% endif %}
</div>
{% endif %}
{% endfor %}
</div>
```
(function() {
var $ = window.jQuery
var Waypoint = window.Waypoint
/* http://imakewebthings.com/waypoints/shortcuts/infinite-scroll */
function InfinitePrepend(options) {
this.options = $.extend({}, InfinitePrepend.defaults, options)
this.container = this.options.element
if (this.options.container !== 'auto') {
this.container = this.options.container
}
this.$container = $(this.container)
this.$more = $(this.options.more)
if (this.$more.length) {
this.setupHandler()
this.waypoint = new Waypoint(this.options)
}
}
/* Private */
InfinitePrepend.prototype.setupHandler = function() {
this.options.handler = $.proxy(function() {
this.options.onBeforePageLoad()
this.destroy()
this.$container.addClass(this.options.loadingClass)
$.get($(this.options.more).attr('href'), $.proxy(function(data) {
var $data = $($.parseHTML(data))
var $newMore = $data.find(this.options.more)
var $items = $data.find(this.options.items)
if (!$items.length) {
$items = $data.filter(this.options.items)
}
this.$container.after($items)
this.$container.removeClass(this.options.loadingClass)
if (!$newMore.length) {
$newMore = $data.filter(this.options.more)
}
if ($newMore.length) {
this.$more.replaceWith($newMore)
this.$more = $newMore
this.waypoint = new Waypoint(this.options)
}
else {
this.$more.remove()
}
this.options.onAfterPageLoad($items)
}, this))
}, this)
}
/* Public */
InfinitePrepend.prototype.destroy = function() {
if (this.waypoint) {
this.waypoint.destroy()
}
}
InfinitePrepend.defaults = {
context: $("#chat-content")[0],
element: $("#trigger-load")[0],
container: $("#trigger-load")[0],
offset: 0,
items: '.infinite-item',
more: '.infinite-more-link',
loadingClass: 'infinite-loading',
onBeforePageLoad: $.noop,
onAfterPageLoad: $.noop
}
Waypoint.InfinitePrepend = InfinitePrepend
}())
;
$(function(){
$(".infinite-container-chat").fadeIn(500).scrollTop($(".infinite-container-chat")[0].scrollHeight);
if($('.infinite-container-chat')[0]){
let infinite_chat = new Waypoint.InfinitePrepend({
onBeforePageLoad: function () {
$('.spinner-border').show();
},
onAfterPageLoad: function () {
$('.spinner-border').hide();
},
})
}
})
Я хочу запустить путевую точку, когда div с id trigger-load попадает в верхнюю часть области просмотра (div с id chat-content). Все загруженные элементы должны быть после div, который запускает путевую точку (я изменил метод append на after).
Я разобрался в проблеме. Код в setupHandler не вычислял новую путевую точку так, как я ожидал. Я просто изменил код, чтобы не уничтожать текущую путевую точку при добавлении элементов после выбранного контейнера. Я уничтожаю ее только тогда, когда нет новых элементов. Я изменил js и html следующим образом:
Единственная проблема с этим кодом заключается в том, что он срабатывает один раз во время загрузки страницы, даже если я откладываю инициализацию путевой точки после прокрутки до нижней части div, но в моем случае это поведение терпимо. Если кто-то найдет решение этой проблемы, не стесняйтесь поделиться. Я также был немного ленив с опциями по умолчанию, поэтому я прокомментировал их, чтобы вы знали, как настроить их самостоятельно.