scrollIntoView 너무 멀리 스크롤
div가있는 테이블 행을 포함하는 스크롤 막대가 데이터베이스에서 동적으로 생성되는 페이지가 있습니다. 각 표 행은 동영상 플레이어 옆의 YouTube 재생 목록에서 볼 수있는 것과 같은 링크처럼 작동합니다.
사용자가 페이지를 방문하면 해당 옵션이 스크롤 div의 맨 위로 이동해야합니다. 이 기능이 작동 중입니다. 문제는 그것이 너무 멀리 가고 있다는 것입니다. 그들이 켜져있는 옵션처럼 약 10px가 너무 높습니다. 따라서 페이지를 방문하고 URL을 사용하여 선택한 옵션을 식별 한 다음 해당 옵션을 스크롤 div의 맨 위로 스크롤합니다. 참고 : 이것은 창의 스크롤 막대가 아니라 스크롤 막대가있는 div입니다.
이 코드를 사용하여 선택한 옵션을 div의 맨 위로 이동합니다.
var pathArray = window.location.pathname.split( '/' );
var el = document.getElementById(pathArray[5]);
el.scrollIntoView(true);
div의 맨 위로 이동하지만 약 10 픽셀이 너무 멀어집니다. 누구든지 그것을 고치는 방법을 알고 있습니까?
약 10px이면 포함하는 div
의 스크롤 오프셋을 다음과 같이 수동으로 조정할 수 있다고 생각합니다 .
el.scrollIntoView(true);
document.getElementById("containingDiv").scrollTop += 10;
두 단계로 수행 할 수 있습니다.
el.scrollIntoView(true);
window.scrollBy(0, -10); // Adjust scrolling with a negative value here
절대 방법으로 위치 앵커
이를 수행하는 또 다른 방법은 오프셋으로 스크롤하는 대신 페이지에서 원하는 위치에 앵커를 정확히 배치하는 것입니다. 각 요소를 더 잘 제어 할 수 있으며 (예 : 특정 요소에 대해 다른 오프셋을 원하는 경우) 브라우저 API 변경 / 차이에 더 저항 할 수 있습니다.
<div id="title-element" style="position: relative;">
<div id="anchor-name" style="position: absolute; top: -100px; left: 0" />
</div>
이제 오프셋은 요소에 대해 -100px로 지정됩니다. 코드 재사용을 위해이 앵커를 생성하는 함수를 생성하거나 React와 같은 최신 JS 프레임 워크를 사용하는 경우 앵커를 렌더링하는 구성 요소를 생성하여이를 수행하고 각 요소에 대한 앵커 이름과 정렬을 전달합니다. 동일하지 않습니다.
그런 다음 사용하십시오.
const element = document.getElementById('anchor-name')
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
100px의 오프셋으로 부드러운 스크롤을 위해.
적절한 위치로 부드럽게 스크롤
정확한 y
좌표를 얻고 사용window.scrollTo({top: y, behavior: 'smooth'})
const id = 'profilePhoto';
const yOffset = -10;
const element = document.getElementById(id);
const y = element.getBoundingClientRect().top + window.pageYOffset + yOffset;
window.scrollTo({top: y, behavior: 'smooth'});
이것은 Chrome에서 나를 위해 작동합니다 (부드러운 스크롤링과 타이밍 해킹 없음)
요소를 이동하고 스크롤을 시작한 다음 뒤로 이동합니다.
요소가 이미 화면에있는 경우 눈에 보이는 "팝핑"이 없습니다.
pos = targetEle.style.position;
top = targetEle.style.top;
targetEle.style.position = 'relative';
targetEle.style.top = '-20px';
targetEle.scrollIntoView({behavior: 'smooth', block: 'start');
targetEle.style.top = top;
targetEle.style.position = pos;
옵션을 사용할 수도 있습니다.element.scrollIntoView()
el.scrollIntoView(
{
behavior: 'smooth',
block: 'start'
},
);
대부분의 브라우저가 지원하는
이전 답변을 바탕으로 Angular5 프로젝트에서 이것을 수행하고 있습니다.
시작 :
// el.scrollIntoView(true);
el.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
window.scrollBy(0, -10);
그러나 이것은 몇 가지 문제를 일으키고 다음과 같이 scrollBy ()에 대한 setTimeout이 필요했습니다.
//window.scrollBy(0,-10);
setTimeout(() => {
window.scrollBy(0,-10)
}, 500);
MSIE11 및 Chrome 68+에서 완벽하게 작동합니다. 나는 FF에서 테스트하지 않았습니다. 500ms는 제가 할 수있는 가장 짧은 지연이었습니다. 부드러운 스크롤이 아직 완료되지 않았기 때문에 때때로 아래로 내려가는 데 실패했습니다. 자신의 프로젝트에 맞게 조정하십시오.
이 간단하지만 효과적인 솔루션 을 위해 Fred727 에게 +1하십시오 .
DOM에서 모두 동일한 수준에 있고 클래스 이름이 "scroll-with-offset"인 div로 스크롤하려는 경우이 CSS가 문제를 해결합니다.
.scroll-with-offset {
padding-top: 100px;
margin-bottom: -100px;
}
페이지 상단으로부터의 오프셋은 100px입니다. block : 'start'에서 의도 한 대로만 작동합니다.
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
What's happening is that the divs' top point is at the normal location but their inner contents start 100px below the normal location. That's what padding-top:100px is for. margin-bottom: -100px is to offset the below div's extra margin. To make the solution complete also add this CSS to offset the margins/paddings for the top-most and bottom-most divs:
.top-div {
padding-top: 0;
}
.bottom-div {
margin-bottom: 0;
}
I've got this and it works brilliantly for me:
// add a smooth scroll to element
scroll(el) {
el.scrollIntoView({
behavior: 'smooth',
block: 'start'});
setTimeout(() => {
window.scrollBy(0, -40);
}, 500);}
Hope it helps.
My main idea is creating a tempDiv above the view which we want to scroll to. It work well without lagging in my project.
scrollToView = (element, offset) => {
var rect = element.getBoundingClientRect();
var targetY = rect.y + window.scrollY - offset;
var tempDiv;
tempDiv = document.getElementById("tempDiv");
if (tempDiv) {
tempDiv.style.top = targetY + "px";
} else {
tempDiv = document.createElement('div');
tempDiv.id = "tempDiv";
tempDiv.style.background = "#F00";
tempDiv.style.width = "10px";
tempDiv.style.height = "10px";
tempDiv.style.position = "absolute";
tempDiv.style.top = targetY + "px";
document.body.appendChild(tempDiv);
}
tempDiv.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
Example using
onContactUsClick = () => {
this.scrollToView(document.getElementById("contact-us"), 48);
}
Hope it help
Most simple solution that works for me:
$('html, body').animate({ scrollTop: $(yourElement).offset().top - 20}, 800);
Based on the answer of Arseniy-II: I had the Use-Case where the scrolling entity was not window itself but a inner Template (in this case a div). In this scenario we need to set an ID for the scrolling container and get it via getElementById
to use its scrolling function:
<div class="scroll-container" id="app-content">
...
</div>
const yOffsetForScroll = -100
const y = document.getElementById(this.idToScroll).getBoundingClientRect().top;
const main = document.getElementById('app-content');
main.scrollTo({
top: y + main.scrollTop + yOffsetForScroll,
behavior: 'smooth'
});
Leaving it here in case someone faces a similar situation!
참고URL : https://stackoverflow.com/questions/24665602/scrollintoview-scrolls-just-too-far
'developer tip' 카테고리의 다른 글
jQuery로 HTTP 상태 코드를 얻으려면 어떻게해야합니까? (0) | 2020.11.19 |
---|---|
문자열에 알파벳 문자가 포함되어 있는지 어떻게 확인할 수 있습니까? (0) | 2020.11.19 |
Android WebView에서 확대 / 축소 활성화 / 비활성화 (0) | 2020.11.19 |
각도 4 단위 테스트 오류`TypeError : ctor is not a constructor` (0) | 2020.11.19 |
null을 확인하고 그렇지 않은 경우 다른 값을 할당하는 가장 짧은 방법 (0) | 2020.11.19 |