Как перейти к элементу внутри div? - PullRequest
123 голосов
/ 11 марта 2009

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

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

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

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

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

Ответы [ 12 ]

288 голосов
/ 20 октября 2009

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

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

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

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

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

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

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

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

64 голосов
/ 11 марта 2009

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

divElem.scrollTop = 0;

Обновление

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

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

  function move_down() {
    document.getElementById('divElem').scrollTop -= 10;
  }
22 голосов
/ 24 июня 2018

Метод 1 - Плавная прокрутка к элементу внутри элемента

var box = document.querySelector('.box'),
    targetElm = document.querySelector('.boxChild'); // <-- Scroll to here within ".box"

document.querySelector('button').addEventListener('click', function(){
   scrollToElm( box, targetElm , 600 );   
});


/////////////

function scrollToElm(container, elm, duration){
  var pos = getRelativePos(elm);
  scrollTo( container, pos.top , 2);  // duration in seconds
}

function getRelativePos(elm){
  var pPos = elm.parentNode.getBoundingClientRect(), // parent pos
      cPos = elm.getBoundingClientRect(), // target pos
      pos = {};

  pos.top    = cPos.top    - pPos.top + elm.parentNode.scrollTop,
  pos.right  = cPos.right  - pPos.right,
  pos.bottom = cPos.bottom - pPos.bottom,
  pos.left   = cPos.left   - pPos.left;

  return pos;
}
    
function scrollTo(element, to, duration, onDone) {
    var start = element.scrollTop,
        change = to - start,
        startTime = performance.now(),
        val, now, elapsed, t;

    function animateScroll(){
        now = performance.now();
        elapsed = (now - startTime)/1000;
        t = (elapsed/duration);

        element.scrollTop = start + change * easeInOutQuad(t);

        if( t < 1 )
            window.requestAnimationFrame(animateScroll);
        else
            onDone && onDone();
    };

    animateScroll();
}

function easeInOutQuad(t){ return t<.5 ? 2*t*t : -1+(4-2*t)*t };
.box{ width:80%; border:2px dashed; height:180px; overflow:auto; }
.boxChild{ 
  margin:600px 0 300px; 
  width: 40px;
  height:40px;
  background:green;
}
<button>Scroll to element</button>
<div class='box'>
  <div class='boxChild'></div>
</div>

Метод 2 - Использование Element.scrollIntoView :

Обратите внимание, что поддержка браузера не подходит для этого

var box = document.querySelector('.box'),
    targetElm = document.querySelector('.boxChild');

document.querySelector('button').addEventListener('click', function(){
   targetElm.scrollIntoView(); 
});
.box {
  width: 80%;
  border: 2px dashed;
  height: 180px;
  overflow: auto;
  scroll-behavior: smooth; /* <-- for smooth scroll */
}

.boxChild {
  margin: 600px 0 300px;
  width: 40px;
  height: 40px;
  background: green;
}
<button>Scroll to element</button>
<div class='box'>
  <div class='boxChild'></div>
</div>

Метод 3 - Использование CSS scroll-поведение :

.box {
  width: 80%;
  border: 2px dashed;
  height: 180px;
  overflow-y: scroll;
  scroll-behavior: smooth; /* <--- */
}

#boxChild {
  margin: 600px 0 300px;
  width: 40px;
  height: 40px;
  background: green;
}
<a href='#boxChild'>Scroll to element</a>
<div class='box'>
  <div id='boxChild'></div>
</div>
9 голосов
/ 20 октября 2015

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

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;

и т. Д.

7 голосов
/ 24 августа 2017

Чтобы прокрутить элемент в виде элемента 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>
4 голосов
/ 20 июня 2017

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

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

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

1 голос
/ 05 марта 2019

Есть два факта:

1) Компонент scrollIntoView не поддерживается safari.

2) JS Framework JQuery может выполнять работу следующим образом:

parent = 'some parent div has css position==="fixed"' || 'html, body';

$(parent).animate({scrollTop: $(child).offset().top}, duration)
1 голос
/ 24 января 2018

Вот простое чистое решение JavaScript, которое работает для целевого числа (значение для scrollTop), целевого элемента DOM или некоторых особых строковых случаев:

/**
 * target - target to scroll to (DOM element, scrollTop Number, 'top', or 'bottom'
 * containerEl - DOM element for the container with scrollbars
 */
var scrollToTarget = function(target, containerEl) {
    // Moved up here for readability:
    var isElement = target && target.nodeType === 1,
        isNumber = Object.prototype.toString.call(target) === '[object Number]';

    if (isElement) {
        containerEl.scrollTop = target.offsetTop;
    } else if (isNumber) {
        containerEl.scrollTop = target;
    } else if (target === 'bottom') {
        containerEl.scrollTop = containerEl.scrollHeight - containerEl.offsetHeight;
    } else if (target === 'top') {
        containerEl.scrollTop = 0;
    }
};

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

// Scroll to the top
var scrollableDiv = document.getElementById('scrollable_div');
scrollToTarget('top', scrollableDiv);

или

// Scroll to 200px from the top
var scrollableDiv = document.getElementById('scrollable_div');
scrollToTarget(200, scrollableDiv);

или

// Scroll to targetElement
var scrollableDiv = document.getElementById('scrollable_div');
var targetElement= document.getElementById('target_element');
scrollToTarget(targetElement, scrollableDiv);
0 голосов
/ 21 марта 2019
Браузер

выполняет автоматическую прокрутку до элемента, который получает фокус, так что вы также можете сделать это, чтобы обернуть элемент, к которому нужно перейти, в <a>...</a>, а затем при необходимости прокрутки просто установите фокус на * 1002. *

0 голосов
/ 23 мая 2018

Еще один пример использования jQuery и animate.

var container = $('#container');
var element = $('#element');

container.animate({
    scrollTop: container.scrollTop = container.scrollTop() + element.offset().top - container.offset().top
}, {
    duration: 1000,
    specialEasing: {
        width: 'linear',
        height: 'easeOutBounce'
    },
    complete: function (e) {
        console.log("animation completed");
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...