programing tip

JavaScript를 사용하여 요소를 어떻게 스크롤합니까?

itbloger 2020. 7. 22. 08:19
반응형

JavaScript를 사용하여 요소를 어떻게 스크롤합니까?


페이지를 <div>요소 로 이동하려고합니다 .

다음 코드를 사용해 보았습니다.

document.getElementById("divFirst").style.visibility = 'visible';
document.getElementById("divFirst").style.display = 'block';

앵커를 사용하여 div에 "포커스"할 수 있습니다. 즉 :

<div id="myDiv"></div>

다음 자바 스크립트를 사용하십시오.

// the next line is required to work around a bug in WebKit (Chrome / Safari)
location.href = "#";
location.href = "#myDiv";

scrollIntoView가 잘 작동합니다.

document.getElementById("divFirst").scrollIntoView();

MDN 문서에서 전체 참조 :
https://developer.mozilla.org/en-US/docs/Web/API/Element.scrollIntoView


귀하의 질문과 답변이 다르게 보입니다. 실수인지 모르겠지만 Google에 접속하여 여기에 도달하는 사람들의 경우 내 대답은 다음과 같습니다.

  1. stackoverflow에 대한 나의 대답
  2. 비슷한 질문

내 답변은 다음과 같이 설명했다.

여기에 간단한 자바 스크립트가 있습니다.

id = "yourSpecificElementId"가있는 요소로 화면을 스크롤해야 할 때 이것을 호출하십시오.

window.scroll(0,findPos(document.getElementById("yourSpecificElementId")));

즉. 위의 질문에 대해, ID가 'divFirst'인 div로 화면을 스크롤하려는 경우

코드는 다음과 같습니다. window.scroll(0,findPos(document.getElementById("divFirst")));

작업 에이 기능이 필요합니다.

//Finds y value of given object
function findPos(obj) {
    var curtop = 0;
    if (obj.offsetParent) {
        do {
            curtop += obj.offsetTop;
        } while (obj = obj.offsetParent);
    return [curtop];
    }
}

화면이 특정 요소로 스크롤됩니다.


Chrome 및 Firefox

나는 이것에 대해 조금 보았고 어떻게 든 가장 자연스러운 방법처럼 느껴지는 것을 알아 냈습니다. 물론 이것은 제가 개인적으로 가장 좋아하는 스크롤입니다. :)

const y = element.getBoundingClientRect().top + window.scrollY;
window.scroll({
  top: y,
  behavior: 'smooth'
});

IE, Edge 및 Safari 서포터

이 기능은 window.scroll({ ...options })IE, Edge 및 Safari에서 지원되지 않습니다. 이 경우을 사용하는 것이 가장 좋습니다 element.scrollIntoView(). (IE 6에서 지원됨). 부작용없이 옵션을 가장 많이 읽을 수 있습니다 (읽지 : 테스트되지 않음).

이것들은 물론 어떤 브라우저가 사용되는지에 따라 동작하는 함수에 싸여있을 수 있습니다.


이 시도:

var divFirst = document.getElementById("divFirst");
divFirst.style.visibility = 'visible'; 
divFirst.style.display = 'block';  
divFirst.tabIndex = "-1";  
divFirst.focus();

예 : @ :

http://jsfiddle.net/Vgrey/


주어진 요소로 스크롤하려면 아래 에서이 자바 스크립트 전용 솔루션을 만들었습니다.

간단한 사용법 :

EPPZScrollTo.scrollVerticalToElementById('signup_form', 20);

엔진 객체 (필터, fps 값으로 바이올린을 칠 수 있음) :

/**
 *
 * Created by Borbás Geri on 12/17/13
 * Copyright (c) 2013 eppz! development, LLC.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */


var EPPZScrollTo =
{
    /**
     * Helpers.
     */
    documentVerticalScrollPosition: function()
    {
        if (self.pageYOffset) return self.pageYOffset; // Firefox, Chrome, Opera, Safari.
        if (document.documentElement && document.documentElement.scrollTop) return document.documentElement.scrollTop; // Internet Explorer 6 (standards mode).
        if (document.body.scrollTop) return document.body.scrollTop; // Internet Explorer 6, 7 and 8.
        return 0; // None of the above.
    },

    viewportHeight: function()
    { return (document.compatMode === "CSS1Compat") ? document.documentElement.clientHeight : document.body.clientHeight; },

    documentHeight: function()
    { return (document.height !== undefined) ? document.height : document.body.offsetHeight; },

    documentMaximumScrollPosition: function()
    { return this.documentHeight() - this.viewportHeight(); },

    elementVerticalClientPositionById: function(id)
    {
        var element = document.getElementById(id);
        var rectangle = element.getBoundingClientRect();
        return rectangle.top;
    },

    /**
     * Animation tick.
     */
    scrollVerticalTickToPosition: function(currentPosition, targetPosition)
    {
        var filter = 0.2;
        var fps = 60;
        var difference = parseFloat(targetPosition) - parseFloat(currentPosition);

        // Snap, then stop if arrived.
        var arrived = (Math.abs(difference) <= 0.5);
        if (arrived)
        {
            // Apply target.
            scrollTo(0.0, targetPosition);
            return;
        }

        // Filtered position.
        currentPosition = (parseFloat(currentPosition) * (1.0 - filter)) + (parseFloat(targetPosition) * filter);

        // Apply target.
        scrollTo(0.0, Math.round(currentPosition));

        // Schedule next tick.
        setTimeout("EPPZScrollTo.scrollVerticalTickToPosition("+currentPosition+", "+targetPosition+")", (1000 / fps));
    },

    /**
     * For public use.
     *
     * @param id The id of the element to scroll to.
     * @param padding Top padding to apply above element.
     */
    scrollVerticalToElementById: function(id, padding)
    {
        var element = document.getElementById(id);
        if (element == null)
        {
            console.warn('Cannot find element with id \''+id+'\'.');
            return;
        }

        var targetPosition = this.documentVerticalScrollPosition() + this.elementVerticalClientPositionById(id) - padding;
        var currentPosition = this.documentVerticalScrollPosition();

        // Clamp.
        var maximumScrollPosition = this.documentMaximumScrollPosition();
        if (targetPosition > maximumScrollPosition) targetPosition = maximumScrollPosition;

        // Start animation.
        this.scrollVerticalTickToPosition(currentPosition, targetPosition);
    }
};

다음은 고정 헤더에 대한 선택적 오프셋을 포함 할 수있는 기능입니다. 외부 라이브러리가 필요하지 않습니다.

function scrollIntoView(selector, offset = 0) {
  window.scroll(0, document.querySelector(selector).offsetTop - offset);
}

JQuery를 사용하여 요소의 높이를 잡고 스크롤 할 수 있습니다.

var headerHeight = $('.navbar-fixed-top').height();
scrollIntoView('#some-element', headerHeight)

2018 년 3 월 업데이트

JQuery를 사용하지 않고이 답변으로 스크롤하십시오.

scrollIntoView('#answer-44786637', document.querySelector('.top-bar').offsetHeight)

요소에 초점을 맞출 수 있습니다. 보다 잘 작동합니다scrollIntoView

node.setAttribute('tabindex', '-1')

node.focus()

node.removeAttribute('tabindex')


대화 형 요소에만 포커스를 설정할 수 있습니다. Div는 페이지의 논리적 섹션 만 나타냅니다.

아마도 div 주위에 테두리를 설정하거나 색상을 변경하여 포커스를 시뮬레이션 할 수 있습니다. 그리고 그렇습니다. 가시성은 초점이 아닙니다.


div에 tabindex를 추가하면 포커스를 얻을 수 있다고 생각합니다.

<div class="divFirst" tabindex="-1">
</div>

I don't think it's valid though, tabindex can be applied only to a, area, button, input, object, select, and textarea. But give it a try.


Similar to @caveman's solution

const element = document.getElementById('theelementsid');

if (element) {
    window.scroll({
        top: element.scrollTop,
        behavior: 'smooth',
    }) 
}

You can't focus on a div. You can only focus on an input element in that div. Also, you need to use element.focus() instead of display()


After looking around a lot, this is what finally worked for me:

  1. Find/locate div in your dom which has scroll bar. For me, it looked like this : "div class="table_body table_body_div" scroll_top="0" scroll_left="0" style="width: 1263px; height: 499px;"

  2. I located it with this xpath : //div[@class='table_body table_body_div']

  3. Used JavaScript to execute scrolling like this : (JavascriptExecutor) driver).executeScript("arguments[0].scrollLeft = arguments[1];",element,2000);

2000 is the no of pixels I wanted to scroll towards the right. Use scrollTop instead of scrollLeft if you want to scroll your div down.

Note : I tried using scrollIntoView but it didn't work properly because my webpage had multiple divs. It will work if you have only one main window where focus lies. This is the best solution I have come across if you don't want to use jQuery which I didn't want to.


A method i often use to scroll a container to its contents.

/**
@param {HTMLElement} container : element scrolled.
@param {HTMLElement} target : element where to scroll.
@param {number} [offset] : scroll back by offset
*/
var scrollAt=function(container,target,offset){
    if(container.contains(target)){
        var ofs=[0,0];
        var tmp=target;
        while (tmp!==container) {
            ofs[0]+=tmp.offsetWidth;
            ofs[1]+=tmp.offsetHeight;
            tmp=tmp.parentNode;
        }
        container.scrollTop = Math.max(0,ofs[1]-(typeof(offset)==='number'?offset:0));
    }else{
        throw('scrollAt Error: target not found in container');
    }
};

if your whish to override globally, you could also do :

HTMLElement.prototype.scrollAt=function(target,offset){
    if(this.contains(target)){
        var ofs=[0,0];
        var tmp=target;
        while (tmp!==this) {
            ofs[0]+=tmp.offsetWidth;
            ofs[1]+=tmp.offsetHeight;
            tmp=tmp.parentNode;
        }
        container.scrollTop = Math.max(0,ofs[1]-(typeof(offset)==='number'?offset:0));
    }else{
        throw('scrollAt Error: target not found in container');
    }
};

Due to behavior "smooth" doesn't work in Safari, Safari ios, Explorer. I usually write a simple function utilizing requestAnimationFrame

(function(){
    var start;
    var startPos = 0;

    //Navigation scroll page to element
    function scrollTo(timestamp, targetTop){
      if(!start) start = timestamp
      var runtime = timestamp - start
      var progress = Math.min(runtime / 700, 1)

      window.scroll(0, startPos + (targetTop * progress) )

      if(progress >= 1){
        return;
      }else {
        requestAnimationFrame(function(timestamp){
            scrollTo(timestamp, targetTop)
        })
      }
   };

  navElement.addEventListener('click', function(e){

    var target = e.target  //or this 
    var targetTop = _(target).getBoundingClientRect().top
    startPos = window.scrollY

    requestAnimationFrame(function(timestamp){
        scrollTo(timestamp, targetTop)
    })
  }

})();

The best, shortest answer that what works even with animation effects:

var scrollDiv = document.getElementById("myDiv").offsetTop;
window.scrollTo({ top: scrollDiv, behavior: 'smooth'});

If you have a fixed nav bar, just subtract its height from top value, so if your fixed bar height is 70px, line 2 will look like:

window.scrollTo({ top: scrollDiv-70, behavior: 'smooth'});

Explanation: Line 1 gets the element position Line 2 scroll to element position; behavior property adds a smooth animated effect


In case you want to use html, you could just use this:

a href="samplewebsite.com/subdivision.html#id

and make it an html link to the specific element id. Its basically getElementById html version.


try this function

function navigate(divId) {
$j('html, body').animate({ scrollTop: $j("#"+divId).offset().top }, 1500);
}

Pass the div id as parameter it will work I am using it already

참고URL : https://stackoverflow.com/questions/5007530/how-do-i-scroll-to-an-element-using-javascript

반응형