Reputation: 7547
I am trying to move the page to a <div>
element.
I have tried the next code to no avail:
document.getElementById("divFirst").style.visibility = 'visible';
document.getElementById("divFirst").style.display = 'block';
Upvotes: 394
Views: 796597
Reputation: 21
Old way of implementing scroll using Javascript
const btn = document.querySelector('.btnToScroll');
const section = document.querySelector('.scrollToSection');
btn.addEventListener('click',function(){
sectionCords = section.getBoundingClientRect();
window.scrollTo( // we are passing one object into window.scrollTo with required values
{
left:sectionCords.left + window.pageXOffset, //if pageXOffset showing deprication warning then use scrollX
top:sectionCords.top + window.pageYOffset, //if pageYOffset showing deprication warning then use scrollY
behavior:"smooth" //behavior of scroll
}
});
Modern way of implementing scroll using Javascript (works in modern web browsers)
const btn = document.querySelector('.btnToScroll');
const section = document.querySelector('.scrollToSection');
btn.addEventListener('click',function(){
section.scrollIntoView({behavior:"smooth"}); //will smoothly scroll to desired section
});
Upvotes: 2
Reputation: 1790
window.scrollBy()
An alternative to window.scroll()
in @caveman's answer is window.scrollBy()
. The following scrolls the browser window to position the target element at the top of the viewport.
const y = element.getBoundingClientRect().top;
window.scrollBy({
top: y,
behavior: 'smooth'
});
The window.scrollBy()
method has the same wide support as window.scroll()
.
As per the notes section of the MDN entry for the scrollBy
method:
window.scrollBy()
scrolls by a particular amount, whereaswindow.scroll()
scrolls to an absolute position in the document.
The formula used in @caveman's post to calculate the scroll-to value is:
const y = window.scrollY + element.getBoundingClientRect().top;
This formula gets the current absolute position (window.scrollY
) and adds the delta of the element
's bounding rectangle top position (relative to the top of the viewport).
The retrieval of the value returned by window.scrollY
(the current absolute position) is not necessary as the y-scroll position of the browser window will only change by the value returned by element.getBoundingClientRect().top
(i.e. a relative value change).
The following sample shows the positioning of a target element at the top, vertical middle, or bottom of the viewport using the window.scrollBy()
method.
const headerElem = document.querySelector("header");
document.querySelectorAll("form.scroll-by > button")
.forEach(elem => elem.addEventListener("click", scrollByClickListener));
function scrollByClickListener() {
const targetId = this.getAttribute("data-target-id");
if (!targetId) {
return;
}
const targetElem = document.querySelector(`#${targetId}`);
if (!targetElem) {
return;
}
const position = this.getAttribute("data-position");
if (!position) {
return;
}
scrollElemIntoView(targetElem, position);
}
function scrollElemIntoView(targetElem, position) {
let scrollByY = 0;
switch (position) {
case "top":
scrollByY = targetElem.getBoundingClientRect().top -
headerElem.getBoundingClientRect().height;
break;
case "middle":
const rect = targetElem.getBoundingClientRect();
scrollByY = rect.top -
window.innerHeight / 2 +
rect.height / 2 -
headerElem.getBoundingClientRect().height / 2;
break;
case "bottom":
scrollByY = targetElem.getBoundingClientRect().bottom -
window.innerHeight;
break;
default:
return;
}
window.scrollBy({
top: scrollByY,
behavior: 'smooth'
});
}
header {
position: fixed;
top: 0;
left: 0;
width: 100%;
background-color: white;
border-bottom: 1px solid black;
padding: 1rem;
}
form.scroll-by {
position: fixed;
display: grid;
grid-gap: 0.5rem;
left: 50%;
transform: translateX(-50%);
}
form.scroll-by button {
padding: 0.5rem;
}
#target-elements>div {
height: 10rem;
margin-bottom: 1rem;
background-color: cornflowerblue;
border: 1px solid red;
}
<header><span>Fixed Header Element</span></header>
<form class="scroll-by">
<button type="button" data-position="top" data-target-id="target-4">Top (target 4)</button>
<button type="button" data-position="middle" data-target-id="target-3">Vertical Middle (target 3)</button>
<button type="button" data-position="bottom" data-target-id="target-6">Bottom (target 6)</button>
</form>
<div id="target-elements">
<div id="target-1">Target 1</div>
<div id="target-2">Target 2</div>
<div id="target-3">Target 3</div>
<div id="target-4">Target 4</div>
<div id="target-5">Target 5</div>
<div id="target-6">Target 6</div>
<div id="target-7">Target 7</div>
<div id="target-8">Target 8</div>
</div>
Upvotes: 4
Reputation: 2955
I've been looking a bit into this and I figured this one out which somehow feels like the most natural way to do it. Of course, this is my personal favorite scroll now. :)
const y = element.getBoundingClientRect().top + window.scrollY;
window.scroll({
top: y,
behavior: 'smooth'
});
Note that window.scroll({ ...options })
is not supported on IE, Edge and Safari. In that case it's most likely best to use
element.scrollIntoView()
. (Supported on IE 6). You can most likely (read: untested) pass in options without any side effects.
These can of course be wrapped in a function that behaves according to which browser is being used.
Upvotes: 115
Reputation: 2693
JS:
document.getElementById('targetid').scrollIntoView({behavior: 'smooth'});
USE with inline HTML :
<p class="text-notification">Some Notification <span style="color:blue;cursor:pointer;" onClick="document.getElementById('target').scrollIntoView({behavior: 'smooth'});">Go to target<span></p>
Upvotes: 5
Reputation: 21
If you simply want to scroll to the bottom of a list that is inside a div, you can do this.
<body>
<div class="container">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="box">7</div>
<div class="box">8</div>
<div class="box">9</div>
</div>
<button>Scroll To</button>
<script>
const btn = document.querySelector("button");
const container = document.querySelector(".container");
btn.addEventListener("click",()=>{
const toplast = document.querySelector(".container").lastElementChild;
toplast.scrollIntoView();
})
</script>
</body>
Upvotes: 2
Reputation: 4160
You can use an anchor to "focus" the div. I.e:
<div id="myDiv"></div>
and then use the following javascript:
// the next line is required to work around a bug in WebKit (Chrome / Safari)
location.href = "#";
location.href = "#myDiv";
Upvotes: 198
Reputation: 777
We can implement by 3 Methods:
Note:
"automatic-scroll" => The particular element
"scrollable-div" => The scrollable area div
Method 1:
document.querySelector('.automatic-scroll').scrollIntoView({
behavior: 'smooth'
});
Method 2:
location.href = "#automatic-scroll";
Method 3:
$('#scrollable-div').animate({
scrollTop: $('#automatic-scroll').offset().top - $('#scrollable-div').offset().top +
$('#scrollable-div').scrollTop()
})
Important notice: method 1 & method 2 will be useful if the scrollable area height is "auto". Method 3 is useful if we using the scrollable area height like "calc(100vh - 200px)".
Upvotes: 37
Reputation: 10620
scrollIntoView works well:
document.getElementById("divFirst").scrollIntoView();
full reference in the MDN docs:
https://developer.mozilla.org/en-US/docs/Web/API/Element.scrollIntoView
Upvotes: 629
Reputation: 2154
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
Upvotes: 55
Reputation: 169
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)
})
}
})();
Upvotes: 1
Reputation: 664
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');
}
};
Upvotes: 2
Reputation: 403
You can set focus to element. It works better than scrollIntoView
node.setAttribute('tabindex', '-1')
node.focus()
node.removeAttribute('tabindex')
Upvotes: 18
Reputation: 3525
Similar to @caveman's solution
const element = document.getElementById('theelementsid');
if (element) {
window.scroll({
top: element.scrollTop,
behavior: 'smooth',
})
}
Upvotes: 2
Reputation: 10114
Here's a function that can include an optional offset for those fixed headers. No external libraries needed.
function scrollIntoView(selector, offset = 0) {
window.scroll(0, document.querySelector(selector).offsetTop - offset);
}
You can grab the height of an element using JQuery and scroll to it.
var headerHeight = $('.navbar-fixed-top').height();
scrollIntoView('#some-element', headerHeight)
Update March 2018
Scroll to this answer without using JQuery
scrollIntoView('#answer-44786637', document.querySelector('.top-bar').offsetHeight)
Upvotes: 7
Reputation: 1
After looking around a lot, this is what finally worked for me:
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;"
I located it with this xpath : //div[@class='table_body table_body_div']
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.
Upvotes: 0
Reputation: 32
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
Upvotes: -4
Reputation: 11
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.
Upvotes: -1
Reputation: 16588
To scroll to a given element, just made this javascript only solution below.
Simple usage:
EPPZScrollTo.scrollVerticalToElementById('signup_form', 20);
Engine object (you can fiddle with filter, fps values):
/**
*
* 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);
}
};
Upvotes: 6
Reputation: 82893
Try this:
var divFirst = document.getElementById("divFirst");
divFirst.style.visibility = 'visible';
divFirst.style.display = 'block';
divFirst.tabIndex = "-1";
divFirst.focus();
e.g @:
Upvotes: 12
Reputation: 21275
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()
Upvotes: 0
Reputation: 21884
I think that if you add a tabindex to your div, it will be able to get focus:
<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.
Upvotes: 0
Reputation: 4503
Focus can be set on interactive elements only... Div only represent a logical section of the page.
Perhaps you can set the borders around div or change it's color to simulate a focus. And yes Visiblity is not focus.
Upvotes: 1