Предотвратить перемещение области просмотра при удалении элементов DOM

Я пытаюсь реализовать бесконечный скроллер HTML, в котором в любой момент времени в списке есть только несколько элементов div (чтобы сохранить небольшой объем памяти).

Я добавляю в список новый элемент div и одновременно удаляю первый, поэтому общее количество div остается прежним.

К сожалению, область просмотра не остается на месте, а вместо этого немного отскакивает назад (фактически на высоту удаленного div). Есть ли способ сохранить область просмотра при удалении div из списка?

Я сделал небольшую автономную HTML-страницу (ну, ей все еще нужен JQuery 3.4.1), которая раскрывает проблему: она начинается с добавления 5 div, а затем продолжает добавлять новый и удалять первый каждую 1 секунду.

function getRandomColor() {
  var letters = '0123456789ABCDEF';
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}

function removeit() {
  // remove first one
  var tiles = $(".tile");
  $(tiles[0]).remove();
}

function addit() {
  // append new one
  var jqueryTextElem = $('<div class = "tile" style = "height:100px;background-color:' + getRandomColor() + '"></div>');
  $("#inner-wrap").append(jqueryTextElem);
}

function loop() {
  removeit();

  addit();

  window.setTimeout(loop, 1000);
}

addit();
addit();
addit();
addit();
addit();

loop();
<div id = "inner-wrap"></div>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

Если убрать топ div, угадайте, какой новый топ div? следующий, заставляя браузер перерисовывать и, следовательно, эффект прыжка. IMO, вы заставляете браузер выполнять больше работы, вы должны оставить внешние div как есть, и вы можете удалить внутренние вещи, если вас больше беспокоят дополнительные элементы DOM.

Rikin 30.05.2019 14:51

@Rikin Чего я действительно пытаюсь добиться, так это бесконечного скроллера, в котором я добавляю еще один div внизу и удаляю div сверху, сохраняя количество div на низком уровне. Пока я буду иметь дело только с прокруткой вниз. Следующий шаг будет идти вверх, что означает добавление нового div сверху и удаление одного снизу.

Gianluca Ghettini 30.05.2019 14:55

Да, поэтому для этой цели вам нужно будет сохранить недвижимость для СТАРЫХ div, если только у вас не будет полосы прокрутки на веб-странице, и в этом случае верхний div в области просмотра всегда будет первым.

Rikin 30.05.2019 14:58

@Rikin Интересно, не могли бы вы уточнить пример или исправить его?

Gianluca Ghettini 30.05.2019 15:01
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
4
1 277
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете временно добавить position: fixed к родительскому элементу:

  1. сначала добавьте position: fixed к родителю;
  2. затем удалите элемент;
  3. затем удалите position: fixed из родителя

Как это работает? Добавление position:fixed удаляет родительский элемент из поля зрения

mss 11.03.2022 07:22

@mss - надеюсь, я смогу помочь, но сначала мне нужно уточнить ваш вопрос. Вы говорите: «Этот подход не работает для меня» или вы говорите: «Я вижу, что этот подход работает, но как он работает?»

Rounin - Glory to UKRAINE 11.03.2022 15:52

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

mss 11.03.2022 18:41

У меня такое чувство, что вы пытаетесь получить свой пирог и съесть его, в том смысле, что если вы сделаете область просмотра «неподвижной», я думаю, вы имеете в виду, что не хотите, чтобы пользователь видел движение полосы прокрутки, а затем также у вас нет новых возможностей прокручивать страницу вниз, потому что вы хотели бы, чтобы ползунок/захват полосы прокрутки все еще находился внизу дорожки полосы прокрутки?

Я имею в виду, что вы могли бы просто использовать $(window).scrollTop($(window).scrollTop() + 100); в своем примере, чтобы сделать так, чтобы положение прокрутки окна просмотра не перемещалось визуально при удалении элементов, но в этот момент вы бы не сохраняли представление пользователей о текущих элементах одинаковым. или даже позволить пользователю иметь новый контент ниже по странице для прокрутки. Вы бы просто «продвигали» контент через представление пользователя?

Если вы пытаетесь облегчить нагрузку на то, что в настоящее время анализируется в документ, потому что вы выполняете тяжелую работу с объектом документа во время выполнения, возможно, вы все еще хотите удалить более ранние элементы, но сохранить их геометрию с некоторым пустым контрольным элементом, который всегда имеет высота всех ранее удаленных элементов, добавленных к нему? Это позволит вам иметь несколько меньший размер (хотя и не с точки зрения макета), но при этом иметь полезную полосу прокрутки, которая может общаться с пользователем, и оба позволяют пользователю прокручивать вниз, к контенту, который был добавлен.

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

Чтобы лучше понять, почему я не думаю, что у вас есть реальная проблема, замените определение loop() чем-то вроде этого...

function loop() {
  $(window).scroll(function() {
    // check for reaching bottom of scroller
    if ($(window).scrollTop() == ($(document).height() - $(window).height())) {
      addit();
      removeit();
    }
  })
}

На самом деле, вот приличная ссылка, которая была только что написана, хотя в ней говорится о реактивной версии этого, в ней излагается, как/почему эти вещи работают так, как они работают. web.dev/virtualize-long-lists-react-window

jonjohnjohnson 25.06.2019 18:54

Другие вопросы по теме