Как перейти к элементу в переполненном Div?
У меня есть 20 элементов списка внутри div, которые могут показывать только 5 за раз. Каков хороший способ прокрутки к элементу № 10, а затем к элементу № 20? Я знаю высоту всех предметов.
Плагин scrollTo
делает это, но его источник не очень легко понять, не вникая в него. Я не хочу использовать этот плагин.
Скажем, у меня есть функция, которая принимает 2 элемента $parentDiv
, $innerListItem
, ни $innerListItem.offset().top
, ни $innerListItem.positon().top
не дает мне правильный scrollTop для $parentDiv.
Ответы
Ответ 1
$innerListItem.position().top
фактически относится к .scrollTop()
его первого позиционированного предка. Таким образом, способ вычисления правильного значения $parentDiv.scrollTop()
заключается в том, чтобы убедиться, что $parentDiv
позиционируется. Если он еще не имеет явного position
, используйте position: relative
. Элементы $innerListItem
и все его предки до $parentDiv
не должны иметь явной позиции. Теперь вы можете перейти к $innerListItem
с помощью:
// Scroll to the top
$parentDiv.scrollTop($parentDiv.scrollTop() + $innerListItem.position().top);
// Scroll to the center
$parentDiv.scrollTop($parentDiv.scrollTop() + $innerListItem.position().top
- $parentDiv.height()/2 + $innerListItem.height()/2);
Ответ 2
Это мой собственный плагин (позиционирует элемент в верхней части списка. Специально для overflow-y : auto
. Может не работать с overflow-x
!):
ПРИМЕЧАНИЕ: elem
- это селектор HTML элемента, к которому будет прокручиваться страница. Все, что поддерживается jQuery, например: #myid
, div.myclass
, $(jquery object)
, [dom object] и т.д.
jQuery.fn.scrollTo = function(elem, speed) {
$(this).animate({
scrollTop: $(this).scrollTop() - $(this).offset().top + $(elem).offset().top
}, speed == undefined ? 1000 : speed);
return this;
};
Если вам не нужна анимация, используйте:
jQuery.fn.scrollTo = function(elem) {
$(this).scrollTop($(this).scrollTop() - $(this).offset().top + $(elem).offset().top);
return this;
};
Как использовать:
$("#overflow_div").scrollTo("#innerItem");
$("#overflow_div").scrollTo("#innerItem", 2000); //custom animation speed
Примечание: #innerItem
может находиться где угодно внутри #overflow_div
. Это действительно не должно быть прямым ребенком.
Протестировано в Firefox (23) и Chrome (28).
Если вы хотите прокрутить всю страницу, отметьте этот вопрос.
Ответ 3
Я скорректировал ответ Гленна Мосса, чтобы учесть тот факт, что div overflow не может быть в верхней части страницы.
parentDiv.scrollTop(parentDiv.scrollTop() + (innerListItem.position().top - parentDiv.position().top) - (parentDiv.height()/2) + (innerListItem.height()/2) )
Я использовал это в приложении Google Maps с помощью адаптивного шаблона. При разрешении > 800 пикселей список находился в левой части карты. По разрешению < 800 этот список был ниже карты.
Ответ 4
Вышеуказанные ответы будут позиционировать внутренний элемент в верхней части элемента переполнения, даже если он отображается внутри элемента переполнения. Я не хотел этого, поэтому я изменил его, чтобы не изменять позицию прокрутки, если элемент находится в поле зрения.
jQuery.fn.scrollTo = function(elem, speed) {
var $this = jQuery(this);
var $this_top = $this.offset().top;
var $this_bottom = $this_top + $this.height();
var $elem = jQuery(elem);
var $elem_top = $elem.offset().top;
var $elem_bottom = $elem_top + $elem.height();
if ($elem_top > $this_top && $elem_bottom < $this_bottom) {
// in view so don't do anything
return;
}
var new_scroll_top;
if ($elem_top < $this_top) {
new_scroll_top = {scrollTop: $this.scrollTop() - $this_top + $elem_top};
} else {
new_scroll_top = {scrollTop: $elem_bottom - $this_bottom + $this.scrollTop()};
}
$this.animate(new_scroll_top, speed === undefined ? 100 : speed);
return this;
};
Ответ 5
Играя с ним в течение очень долгого времени, это то, что я придумал:
jQuery.fn.scrollTo = function (elem) {
var b = $(elem);
this.scrollTop(b.position().top + b.height() - this.height());
};
и я называю это так
$("#basketListGridHolder").scrollTo('tr[data-uid="' + basketID + '"]');