Как прокручивать элемент внутри div?

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

document.getElementById(chr).scrollIntoView(true);

но это прокручивает всю страницу при прокрутке самой div. Как это исправить?

Я хочу сказать так:

MyContainerDiv.getElementById(chr).scrollIntoView(true);

Ответ 1

Вам нужно получить верхнее смещение элемента, который вы хотите прокрутить, в представлении относительно его родителя (контейнера div прокрутки):

var myElement = document.getElementById('element_within_div');
var topPos = myElement.offsetTop;

Теперь переменная topPos устанавливается на расстояние между вершиной прокручиваемого div и элементом, который вы хотите видеть (в пикселях).

Теперь мы сообщим div, чтобы прокрутить эту позицию, используя scrollTop:

document.getElementById('scrolling_div').scrollTop = topPos;

Если вы используете прототип структуры JS, вы бы сделали то же самое, что и здесь:

var posArray = $('element_within_div').positionedOffset();
$('scrolling_div').scrollTop = posArray[1];

Опять же, это прокрутит div так, что элемент, который вы хотите увидеть, находится точно вверху (или, если это невозможно, прокручивается так далеко, насколько это возможно).

Ответ 2

Вам нужно будет найти позицию элемента в DIV, который вы хотите прокрутить, и установить свойство scrollTop.

divElem.scrollTop = 0;

Обновление

Пример кода для перемещения вверх или вниз

  function move_up() {
    document.getElementById('divElem').scrollTop += 10;
  }

  function move_down() {
    document.getElementById('divElem').scrollTop -= 10;
  }

Ответ 3

Код должен быть:

var divElem = document.getElementById('scrolling_div');
var chElem = document.getElementById('element_within_div');
var topPos = divElem.offsetTop;
divElem.scrollTop = topPos - chElem.offsetTop;

Вы хотите прокрутить разницу между верхней позицией ребенка и верхней позицией div.

Получить доступ к дочерним элементам, используя:

var divElem = document.getElementById('scrolling_div'); 
var numChildren = divElem.childNodes.length;

и т.д....

Ответ 4

Если вы используете jQuery, вы можете прокручивать анимацию, используя следующее:

$(MyContainerDiv).animate({scrollTop: $(MyContainerDiv).scrollTop() + ($('element_within_div').offset().top - $(MyContainerDiv).offset().top)});

Анимация необязательна: вы также можете взять значение scrollTop, вычисленное выше, и поместить его непосредственно в контейнер scrollTop свойство.

Ответ 5

Чтобы прокрутить элемент в виде div, только при необходимости вы можете использовать эту функцию scrollIfNeeded:

function scrollIfNeeded(element, container) {
  if (element.offsetTop < container.scrollTop) {
    container.scrollTop = element.offsetTop;
  } else {
    const offsetBottom = element.offsetTop + element.offsetHeight;
    const scrollBottom = container.scrollTop + container.offsetHeight;
    if (offsetBottom > scrollBottom) {
      container.scrollTop = offsetBottom - container.offsetHeight;
    }
  }
}

document.getElementById('btn').addEventListener('click', ev => {
  ev.preventDefault();
  scrollIfNeeded(document.getElementById('goose'), document.getElementById('container'));
});
.scrollContainer {
  overflow-y: auto;
  max-height: 100px;
  position: relative;
  border: 1px solid red;
  width: 120px;
}

body {
  padding: 10px;
}

.box {
  margin: 5px;
  background-color: yellow;
  height: 25px;
  display: flex;
  align-items: center;
  justify-content: center;
}

#goose {
  background-color: lime;
}
<div id="container" class="scrollContainer">
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div id="goose" class="box">goose</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
</div>

<button id="btn">scroll to goose</button>

Ответ 6

Анимированная прокрутка пользователя

Вот пример того, как программно прокручивать <div> по горизонтали, без JQuery. Для прокрутки по вертикали вы вместо этого замените запись JavaScript на scrollLeft на scrollTop.

JSFiddle

https://jsfiddle.net/fNPvf/38536/

HTML

<!-- Left Button. -->
<div style="float:left;">
    <!-- (1) Whilst it pressed, increment the scroll. When we release, clear the timer to stop recursive scroll calls. -->
    <input type="button" value="«" style="height: 100px;" onmousedown="scroll('scroller',3, 10);" onmouseup="clearTimeout(TIMER_SCROLL);"/>
</div>
<!-- Contents to scroll. -->
<div id="scroller" style="float: left; width: 100px; height: 100px; overflow: hidden;">
    <!-- <3 -->
    <img src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png?v=9c558ec15d8a" alt="image large" style="height: 100px" />
</div>
<!-- Right Button. -->
<div style="float:left;">
    <!-- As (1). (Use a negative value of 'd' to decrease the scroll.) -->
    <input type="button" value="»" style="height: 100px;" onmousedown="scroll('scroller',-3, 10);" onmouseup="clearTimeout(TIMER_SCROLL);"/>
</div>

JavaScript

// Declare the Shared Timer.
var TIMER_SCROLL;
/** 
Scroll function. 
@param id  Unique id of element to scroll.
@param d   Amount of pixels to scroll per sleep.
@param del Size of the sleep (ms).*/
function scroll(id, d, del){
    // Scroll the element.
    document.getElementById(id).scrollLeft += d;
    // Perform a delay before recursing this function again.
    TIMER_SCROLL = setTimeout("scroll('"+id+"',"+d+", "+del+");", del);
 }

Кредит Dux.


Автоанимированная прокрутка

Кроме того, здесь функции для прокрутки a <div> полностью влево и вправо. Единственное, что мы здесь изменим, - это проверить, чтобы использовать полное расширение прокрутки, прежде чем сделать рекурсивный вызов для прокрутки снова.

JSFiddle

https://jsfiddle.net/0nLc2fhh/1/

HTML

<!-- Left Button. -->
<div style="float:left;">
    <!-- (1) Whilst it pressed, increment the scroll. When we release, clear the timer to stop recursive scroll calls. -->
    <input type="button" value="«" style="height: 100px;" onclick="scrollFullyLeft('scroller',3, 10);"/>
</div>
<!-- Contents to scroll. -->
<div id="scroller" style="float: left; width: 100px; height: 100px; overflow: hidden;">
  <!-- <3 -->
  <img src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png?v=9c558ec15d8a" alt="image large" style="height: 100px" />
</div>
<!-- Right Button. -->
<div style="float:left;">
    <!-- As (1). (Use a negative value of 'd' to decrease the scroll.) -->
    <input type="button" value="»" style="height: 100px;" onclick="scrollFullyRight('scroller',3, 10);"/>
</div>

JavaScript

// Declare the Shared Timer.
var TIMER_SCROLL;
/** 
Scroll fully left function; completely scrolls  a <div> to the left, as far as it will go.
@param id  Unique id of element to scroll.
@param d   Amount of pixels to scroll per sleep.
@param del Size of the sleep (ms).*/
function scrollFullyLeft(id, d, del){
    // Fetch the element.
    var el = document.getElementById(id);
    // Scroll the element.
    el.scrollLeft += d;
    // Have we not finished scrolling yet?
    if(el.scrollLeft < (el.scrollWidth - el.clientWidth)) {
        TIMER_SCROLL = setTimeout("scrollFullyLeft('"+id+"',"+d+", "+del+");", del);
    }
}

/** 
Scroll fully right function; completely scrolls  a <div> to the right, as far as it will go.
@param id  Unique id of element to scroll.
@param d   Amount of pixels to scroll per sleep.
@param del Size of the sleep (ms).*/
function scrollFullyRight(id, d, del){
    // Fetch the element.
    var el = document.getElementById(id);
    // Scroll the element.
    el.scrollLeft -= d;
    // Have we not finished scrolling yet?
    if(el.scrollLeft > 0) {
        TIMER_SCROLL = setTimeout("scrollFullyRight('"+id+"',"+d+", "+del+");", del);
    }
}