2009-03-11 5 views
76

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

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

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

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

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

Scrolltop не всегда вернуть полезную ценность. Я обычно использую 'SetTimeout' в' $ (document) .ready ({}) 'функцию и устанавливаю' focus() 'для элемента, который вы хотите прокрутить. Работает для меня – DerpyNerd

ответ

211

Вы должны получить сверху смещение элемента вы хотите, чтобы прокрутить в поле зрения, по сравнению с его родителем (контейнер для прокрутки 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 так, что элемент, который вы хотите увидеть, находится точно в верхней части (или, если это невозможно, прокручивается так далеко, насколько это возможно, чтобы оно было видно).

+6

Это было действительно полезно! Если вы хотите установить прокрутку несколько раз, вам необходимо компенсировать текущее местоположение прокрутки. Вот как я это сделал в jQuery: $ ('# scrolling_div'). ScrollTop ($ ('# scrolling_div'). ScrollTop() + $ ('# element_within_div'). Position(). Top); – DenimChicken

+0

больше не работает, offsetTop всегда равен 0 – singe3

+2

Остерегайтесь, что запрос 'myElement.offsetTop' будет вызывать переполнение (разбиение макета), которое может быть [узким местом] [https://developers.google.com/web/ Основы/производительность/рендеринг/избегать-large-complex-layouts-and-layout-thrashing? hl = en # avoid-layout-thrashing) – Kestutis

56

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

divElem.scrollTop = 0; 

Update:

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

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

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

Я хочу прокрутить его, чтобы увидеть его, не прокручивая с определенным значением –

7

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

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; 

и так далее ....

+1

Не должна ли вторая строка читать 'var chElem = document.getElementById ('element_within_div');' и 3-я строка читает 'var topPos = divElem.offsetTop;'? – jayp

0

пользователя Анимированные Scrolling

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

JSFiddle

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

HTML

<!-- Left Button. --> 
<div style="float:left;"> 
    <!-- (1) Whilst it's 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.


Авто Анимированные скроллинг

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

JSFiddle

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

HTML

<!-- Left Button. --> 
<div style="float:left;"> 
    <!-- (1) Whilst it's 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); 
    } 
} 
2

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

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

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

2

Для перемещения элемента в поле зрения в 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>

0

Вот простой чистый раствор 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

Это то, что наконец-то служил мне

/** Set parent scroll to show element 
* @param element {object} The HTML object to show 
* @param parent {object} The HTML object where the element is shown */ 
var scrollToView = function(element, parent) { 
    //Algorithm: Accumulate the height of the previous elements and add half the height of the parent 
    var offsetAccumulator = 0; 
    parent = $(parent); 
    parent.children().each(function() { 
     if(this == element) { 
      return false; //brake each loop 
     } 
     offsetAccumulator += $(this).innerHeight(); 
    }); 
    parent.scrollTop(offsetAccumulator - parent.innerHeight()/2); 
}