2009-03-11 21 views
76

Tengo un div desplazado y quiero tener un enlace cuando hago clic en él forzará este div para desplazarse y ver un elemento dentro. escribí su JavasSript así:¿Cómo desplazarse a un elemento dentro de un div?

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

pero esto pergaminos toda la página, mientras que el desplazamiento de la misma div. ¿Cómo solucionar eso?

Quiero decirlo así

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

scrollTop no siempre devolver un valor utilizable. Tiendo a usar un 'SetTimeout' en la función' $ (document) .ready ({}) 'y establezco' focus() 'en el elemento al que quiero desplazarme. Funciona para mí – DerpyNerd

Respuesta

211

Que necesita para obtener el desplazamiento del elemento desea desplazarse en vista superior, relativo a su elemento primario (el contenedor div desplazable):

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

La variable topPos ahora está configurada en la distancia entre la parte superior del elemento div que se desplaza y el elemento que desea que esté visible (en píxeles).

Ahora nos dicen el div para desplazarse hasta esa posición con scrollTop:

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

Si está utilizando el marco JS prototipo, que harías lo mismo de esta manera:

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

Nuevamente, esto desplazará el div para que el elemento que desea ver esté exactamente en la parte superior (o si eso no es posible, se desplazará lo más abajo posible para que esté visible).

+6

¡Esto fue realmente útil! Si desea configurar el desplazamiento varias veces, necesita compensarlo con su ubicación de desplazamiento actual. He aquí cómo lo hice en jQuery: $ ('# scrolling_div') scrollTop ($ ('# scrolling_div') scrollTop() + $ ('# element_within_div') posición() superior...);. – DenimChicken

+0

ya no funciona, se offsetTop siempre es igual a 0 – singe3

+2

Mira que solicita 'myElement.offsetTop' desencadenará reflujo (golear diseño) que podría ser un [cuello de botella] (https://developers.google.com/web/ ? fundamentos/rendimiento// prestación evitar a gran complejo-diseños-y-diseño-golear hl = es # evitar-layout-golear) – Kestutis

56

Usted tendría que encontrar la posición del elemento en el DIV que desea desplazarse a, y establezca la propiedad scrollTop.

divElem.scrollTop = 0; 

actualización:

Código de ejemplo para desplazarse hacia arriba o hacia abajo

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

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

Quiero desplazarme por su vista, para ver que no se desplaza con un cierto valor –

7

Código debe ser:

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

que desea desplazarse la diferencia entre la posición superior del niño y la posición de la parte superior del div.

consigue el acceso a elementos secundarios usando:

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

y así sucesivamente ....

+1

¿No debería la 2da línea realmente leer 'var chElem = document.getElementById ('element_within_div');' y la 3ra línea leer 'var topPos = divElem.offsetTop;'? – jayp

0

usuario Desplazamiento animado

Aquí está un ejemplo de cómo desplazarse programación un <div> horizontal, sinJQuery. Para desplazarse verticalmente, debe reemplazar las escrituras de JavaScript a scrollLeft con scrollTop, en su lugar.

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

Crédito a Dux.


el desplazamiento automático de animación

Además, aquí están las funciones para el desplazamiento de un <div> completamente hacia la izquierda y la derecha. Lo único que cambiamos aquí es que verifiquemos si se ha utilizado la extensión completa del desplazamiento antes de realizar una llamada recursiva para desplazar nuevamente.

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

Si está utilizando jQuery, puede desplazarse con una animación utilizando la siguiente:

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

La animación es opcional: también se puede tomar el valor calculado anteriormente scrollTop y ponerlo directamente en la propiedad del contenedor scrollTop.

2

Para desplazarse de un elemento a la vista de un div, sólo si es necesario, se puede utilizar este scrollIfNeeded función:

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

he aquí una solución JavaScript puro simple que funciona para un número de destino (valor para scrollTop), orientar elemento DOM, o algunos casos especiales de Cuerda:

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

y aquí están algunos ejemplos de uso:

// 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

Esto es lo que finalmente me ha servido

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