2009-03-11 3 views
76

J'ai un défilement div et je veux avoir un lien quand je clique dessus il va forcer ce div pour faire défiler pour voir un élément à l'intérieur. Je écrit son JavasSript comme ceci:Comment faire défiler jusqu'à un élément à l'intérieur d'une div?

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

mais cela fait défiler toutes les pages tout en faisant défiler la div lui-même. Comment réparer cela?

Je veux le dire comme ça

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

scrollTop ne pas toujours renvoie une valeur utilisable. J'ai tendance à utiliser 'SetTimeout' dans la fonction' $ (document) .ready ({}) 'et à mettre' focus() 'dans l'élément que vous voulez faire défiler. Fonctionne pour moi – DerpyNerd

Répondre

211

Vous devez obtenir le haut décalage de l'élément que vous souhaitez faire défiler en vue, par rapport à son parent (le conteneur div scrolling):

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

La variable topPos est maintenant définie à la distance entre le haut de la div de défilement et l'élément que vous souhaitez avoir visible (en pixels).

Maintenant, nous dire la div pour faire défiler cette position à l'aide scrollTop:

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

Si vous utilisez le cadre prototype JS, vous feriez la même chose comme ceci:

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

Encore une fois, cela fera défiler la div pour que l'élément que vous souhaitez voir soit exactement en haut (ou si ce n'est pas possible, faites défiler le plus bas possible pour le rendre visible).

+6

Cela a été vraiment utile! Si vous souhaitez définir le défilement plusieurs fois, vous devez le décaler en fonction de votre emplacement de défilement actuel. Voici comment je l'ai fait dans jQuery: $ ('# scrolling_div'). ScrollTop ($ ('# scrolling_div'). ScrollTop() + $ ('# element_within_div'). Position(). Top); – DenimChicken

+0

ne fonctionne plus, offsetTop est toujours égal à 0 – singe3

+2

Attention, le fait de demander 'myElement.offsetTop' déclenchera redistribution (mise en page), ce qui pourrait être un [goulot d'étranglement des performances] (https://developers.google.com/web/ – Kestutis

56

Vous devez trouver la position de l'élément dans la DIV que vous voulez faire défiler, et définir la propriété scrollTop.

divElem.scrollTop = 0; 

Mise à jour:

Exemple de code pour déplacer vers le haut ou vers le bas

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

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

je veux faire défiler la vue, de le voir ne pas défiler avec une certaine valeur –

7
code

devrait être:

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

Vous voulez faire défiler la différence entre l'enfant position haute et position supérieure de div.

Obtenir l'accès aux éléments de l'enfant en utilisant:

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

et ainsi de suite ....

+1

La deuxième ligne ne devrait-elle pas lire 'var chElem = document.getElementById ('element_within_div');' et la troisième ligne 'var topPos = divElem.offsetTop;'? – jayp

0

utilisateur animé Scrolling

Voici un exemple de la façon de faire défiler un programme <div> horizontalement, sansJQuery. Pour faire défiler verticalement, vous devez remplacer les écritures de JavaScript par scrollLeft par 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); 
} 

Crédit au Dux.


Animation Auto Scrolling

De plus, voici les fonctions de défilement d'un <div> complètement à gauche et à droite. La seule chose que nous changeons ici est que nous faisons une vérification pour voir si l'extension complète du défilement a été utilisée avant de faire un appel récursif pour faire défiler à nouveau.

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 vous utilisez jQuery, vous pouvez faire défiler avec une animation en utilisant les éléments suivants:

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

L'animation est facultative: vous pouvez également prendre la valeur scrollTop calculée ci-dessus et de le mettre directement dans la propriété scrollTop du conteneur.

2

Pour faire défiler un élément en vue d'une div, seulement si nécessaire, vous pouvez utiliser cette fonction 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

est ici d'une simple solution pure JavaScript qui fonctionne pour un numéro cible (valeur pour scrollTop), la cible élément DOM, ou certains cas de chaînes de caractères spéciaux:

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

Et voici quelques exemples d'utilisation:

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

ou

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

ou

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

C'est ce qui m'a finalement servi

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