2009-03-11 12 views
76

Ho uno scroll div e voglio avere un collegamento quando clicco su di esso costringerà questo div a scorrere per visualizzare un elemento all'interno. Ho scritto la sua JavasSript come questo:Come scorrere verso un elemento all'interno di un div?

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

ma questo Scorre tutta pagina durante lo scorrimento del div stesso. Come risolvere il problema?

voglio dire in quel modo

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

scrollTop non sempre restituire un valore utilizzabile. Tendo ad usare un 'SetTimeout' nella funzione' $ (document) .ready ({}) 'e metto' focus() 'sull'elemento a cui vuoi scorrere. Funziona per me – DerpyNerd

risposta

211

È necessario ottenere l'offset dell'elemento che desideri scorrere in vista dall'alto, relativo al suo genitore (il contenitore a scorrimento div):

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

La variabile topPos è ora impostata sulla distanza tra la parte superiore del div di scorrimento e l'elemento che si desidera avere visibile (in pixel).

Ora diciamo al div per scorrere fino a quella posizione utilizzando scrollTop:

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

Se si sta utilizzando il framework JS prototipo, fareste la stessa cosa come questa:

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

Ancora una volta, questo scorrerà il div in modo che l'elemento che desideri vedere sia esattamente in alto (o se ciò non è possibile, scorri fino in fondo perché sia ​​visibile).

+6

Questo è stato davvero utile! Se si desidera impostare lo scorrimento più volte, è necessario eseguire lo spostamento dalla posizione di scorrimento corrente. Ecco come l'ho fatto in jQuery: $ ('# scrolling_div'). ScrollTop ($ ('# scrolling_div'). ScrollTop() + $ ('# element_within_div'). Position(). Top); – DenimChicken

+0

non funziona più, offsetTop è sempre uguale a 0 – singe3

+2

Attenzione che la richiesta di 'myElement.offsetTop' attiverà il reflow (layout thrashing) che potrebbe essere un [collo di bottiglia delle prestazioni] (https://developers.google.com/web/ fondamentali/prestazioni/rendering/evitare-grandi-complessi-layout-e-layout-thrashing? hl = it # evitare-layout-thrashing) – Kestutis

56

Si dovrà trovare la posizione dell'elemento nel DIV si desidera scorrere fino a, e impostare la proprietà scrollTop.

divElem.scrollTop = 0; 

Aggiornamento:

codice di esempio per spostarsi verso l'alto o verso il basso

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

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

Voglio scorrere la vista, per vederlo non scorrere con un certo valore –

7

codice dovrebbe essere:

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

si desidera scorrere la differenza tra il bambino prima posizione e la posizione superiore del div.

Ottenere l'accesso a elementi figlio utilizzando:

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

e così via ....

+1

Se la seconda riga non dovesse effettivamente leggere 'var chElem = document.getElementById ('element_within_div');' e la 3a riga legge 'var topPos = divElem.offsetTop;'? – jayp

0

utente animate Scorrimento

Ecco un esempio di come scorrere di programmazione un <div> orizzontale, senzaJQuery. Per scorrere verticalmente, sostituirai le scritture JavaScript su scrollLeft con scrollTop, invece.

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); 
} 

Credito a Dux.


Auto animate Scrolling

Inoltre, qui funzioni per lo scorrimento di un <div> completamente a sinistra ea destra. L'unica cosa che cambiamo qui è che facciamo un controllo per vedere se l'intera estensione del rotolo è stata utilizzata prima di effettuare una chiamata ricorsiva per scorrere nuovamente.

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

Se si utilizza jQuery, è possibile scorrere con un'animazione usando la seguente:

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

L'animazione è opzionale: si potrebbe anche prendere il valore scrollTop calcolato sopra e metterlo direttamente in proprietà del contenitore scrollTop.

2

Per scorrere un elemento in vista di un div, solo se necessario, è possibile utilizzare questa funzione 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

Ecco una soluzione JavaScript pura semplice che funziona per un numero di destinazione (valore per scrollTop), elemento DOM di destinazione o alcuni casi String speciali:

/** 
* 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; 
    } 
}; 

Ed ecco alcuni esempi di utilizzo:

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

o

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

o

// Scroll to targetElement 
var scrollableDiv = document.getElementById('scrollable_div'); 
var targetElement= document.getElementById('target_element'); 
scrollToTarget(targetElement, scrollableDiv); 
0

Questo è ciò che mi ha finalmente servito

/** 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); 
} 
Problemi correlati