div 내부의 요소로 스크롤하는 방법은 무엇입니까?


170

스크롤 div이 있고 클릭 할 때 링크를 원하면 div내부 요소를 볼 수 있도록 스크롤됩니다. JavasSript를 다음과 같이 작성했습니다.

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

그러나 이것은 div자체 를 스크롤하면서 모든 페이지를 스크롤합니다 . 그것을 고치는 방법?

그렇게 말하고 싶어

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

Scrolltop이 항상 사용 가능한 값을 반환하지는 않습니다. 함수 SetTimeout에서 a를 사용하고 스크롤하려는 요소로 $(document).ready({})설정 하는 경향이 있습니다 focus(). 나를 위해 작동
DerpyNerd

답변:


341

부모 (스크롤링 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를 스크롤하여 보려는 요소가 정확히 맨 위에 오게합니다 (또는 가능하지 않은 경우 볼 수있는 한 아래로 스크롤합니다).


9
이것은 정말로 도움이되었다! 스크롤을 여러 번 설정하려면 현재 스크롤 위치로 오프셋해야합니다. 다음은 jQuery에서 수행 한 방법입니다. $ ( '# scrolling_div'). scrollTop ($ ( '# scrolling_div'). scrollTop () + $ ( '# element_within_div'). position (). top);
Will

3
요청 myElement.offsetTop하면 성능 병목 현상
Kestutis

27
스크롤 부모를 CSS로 설정해야합니다. position: relative그렇지 않으면 방금했던 것처럼 디버깅하는 데 많은 시간을 소비합니다.
savedario

2
부모 요소 ( ) 의 overflow-y속성 을 설정해야 했습니다. 그렇지 않으면 작동하지 않았습니다. 이 속성 의 기본 CSS 값 은 수동 스크롤도 가능하지만 js 코드는 작동하지 않습니다 ( .. scrollscrolling_divoverflowauto{psition: relative}
와도 같지 않음

2
추가 정보 : .offsetTop은 0을 반환 할 수 있습니다. 그런 다음 부모 요소를 참조하고 다시 시도해야합니다. 나는 태그 h4를 위해 그런 div다음 article태그를하고 article나를 위해 일했다.
Fenio

66

스크롤하려는 DIV에서 요소의 위치를 ​​찾아서 scrollTop 속성을 설정해야합니다.

divElem.scrollTop = 0;

업데이트 :

위 또는 아래로 이동하는 샘플 코드

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

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

3
보기를 스크롤하여 특정 값으로 스크롤하지 않는지 확인합니다.
Amr Elgarhy

39

방법 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 targetElm = document.querySelector('.boxChild'),  // reference to scroll target
    button = document.querySelector('button');        // button that triggers the scroll
  
// bind "click" event to a button 
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 스크롤 동작 사용 :

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


1
스크롤 동작은 IE / Edge / Safari에서 지원되지 않습니다.
sheats

1
@sheats-MDN 문서 링크에서 큰 글꼴 크기로 배치했다고 정확하게 말합니다. 해당 브라우저에서 작동하지 않더라도 사용해서는 안된다는 의미는 아닙니다. "규칙"은 없으며 모든 브라우저에서 모든 것이 동일하게 작동해야합니다. 최신 브라우저가 마법을 발휘할 수 있다면 마법을 사용하십시오.
vsync

이 게시물은 스크롤 가능한 요소가 아닌 전체 문서를 스크롤하는 것에 관한 것입니다.

@ DoMiNeLa10-그건 가정입니다. OP는 자신의 문제를 설명하기위한 임의의 예를 제공했을 수 있습니다. 또한 OP는 주요 관심사가 아니라 오히려 건전한 솔루션을 찾는 검색 엔진에서 오는 사람들이며 OP 요구에 구체적으로 대답하면 도움이되지 않으며이 웹 사이트의 목표는 많은 사람들을 도울 수있는 확실한 답변 을 만드는 것입니다 가능한 한. 내 대답은 모두를 제공합니다 .
vsync

12

필요한 경우에만 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>


1
정말 도움이되었습니다. 컨테이너의 상대 위치를 놓 쳤기 때문에 조금 어려움을 겪었습니다. 그것은 결정적이었습니다!
brohr

11

코드는 다음과 같아야합니다.

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');세 번째 줄을 읽지 않아야 var topPos = divElem.offsetTop;합니까?
jayp

7

jQuery를 사용하는 경우 다음을 사용하여 애니메이션으로 스크롤 할 수 있습니다.

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

애니메이션은 선택 사항입니다. 위에서 계산 한 scrollTop 값을 가져 와서 컨테이너의 scrollTop 속성에 직접 넣을 수도 있습니다 .


5

기본 JS, 크로스 브라우저, 부드러운 스크롤 (업데이트 2020)

설정 ScrollTop하면 원하는 결과가 나오지만 스크롤이 매우 갑작 스럽습니다. jquery부드러운 스크롤을 사용 하는 것은 옵션이 아닙니다. 여기에 모든 주요 브라우저를 지원하는 작업을 수행하는 기본 방법이 있습니다. 참조 -Caniuse

// get the "Div" inside which you wish to scroll (i.e. the container element)
const El = document.getElementById('xyz');

// Lets say you wish to scroll by 100px, 
El.scrollTo({top: 100, behavior: 'smooth'});

// If you wish to scroll until the end of the container
El.scrollTo({top: El.scrollHeight, behavior: 'smooth'});

그게 다야!


여기 의심스러운 사람들을위한 스 니펫이 있습니다.

document.getElementById('btn').addEventListener('click', e => {
  e.preventDefault();
  // smooth scroll
  document.getElementById('container').scrollTo({top: 175, behavior: 'smooth'});
});
/* just some styling for you to ignore */
.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;
}
<!-- Dummy html to be ignored -->
<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">goose</button>

업데이트 : 의견에서 알 수 있듯이 Element.scrollTo()IE11에서는 지원되지 않는 것 같습니다 . 따라서 IE11에 관심이 없다면 (실제로해서는 안되는) 모든 프로젝트에서 자유롭게 사용할 수 있습니다. Edge에 대한 지원이 있습니다. 따라서 Edge / Windows 사용자를 실제로 남기지 않습니다.)

참고


1
scrollTo()Window객체의 경우 모든 주요 브라우저에서 지원되지만 요소의 경우 IE 또는 Edge에서는 지원되지 않습니다.
팀 다운

caniuse 에 따르면 IE11 및 Edge에서 지원됩니다. 이 브라우저에서 개인적으로 테스트하지는 않았지만 지원되는 것 같습니다.
Niket Pathak

1
그건 window.scrollTo아니고 Element.scrollTo. 예를 들어 Edge에서 이것을 시도하고 콘솔을 확인하십시오. codepen.io/timdown/pen/abzVEMB
Tim Down

네 말이 맞아 IE11은 지원되지 않습니다. 그러나 Edge v76 (ref) 이상은 지원되는 것 같습니다
Niket Pathak

2

두 가지 사실이 있습니다.

1) 구성 요소 scrollIntoView는 사파리에서 지원되지 않습니다.

2) JS 프레임 워크 jQuery는 다음과 같은 작업을 수행 할 수 있습니다.

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

$(parent).animate({scrollTop: $(child).offset().top}, duration)

1

다음은 대상 번호 (에 대한 값 scrollTop), 대상 DOM 요소 또는 일부 특수 문자열 경우에 작동하는 간단한 순수 JavaScript 솔루션입니다 .

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

1

jQuery와 애니메이션을 사용하는 또 다른 예.

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

0

사용자 애니메이션 스크롤

다음은 JQuery 없이 프로그래밍 방식으로 <div>가로로 스크롤하는 방법의 예입니다 . 세로로 스크롤하려면 대신 JavaScript 쓰기를 로 바꿉니다. scrollLeftscrollTop

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>

자바 스크립트

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

자바 스크립트

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

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

0

브라우저는 포커스를 얻는 요소로 자동 스크롤하므로 스크롤해야 할 요소를 래핑하고 스크롤해야 할 <a>...</a>때 포커스를 설정하십시오.a


0

요소를 선택한 후 scrollIntoView아래 옵션과 함께 기능을 사용하십시오.

const option = {
  top: 0, // number,
  left: 0, // number,
  behavior: 'auto', // auto or smooth 
    // - auto for one jump motion and smooth for animated motion -
};

따라서이 게시물에 대한 답변은 다음과 같습니다.

const el = document.getElementById('id-name');
el.scrollIntoView({
  top: 0,
  left: 0,
  behavior: 'auto',
});

0

내부에 스크롤 해야하는 div 요소가 있으면이 코드를 사용해보십시오.

document.querySelector('div').scroll(x,y)

이것은 스크롤이있는 div 내부에서 나와 함께 작동합니다.이 요소 위에 마우스를 올려 놓고 아래로 스크롤하려고 할 때와 함께 작동합니다. 수동으로 작동하면 작동해야합니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.