如何使用JavaScript滚动到某个元素?


152

我正在尝试将页面移至某个<div>元素。

我尝试下一个代码无济于事:

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

1
visibility并且display用于使元素(不可见)可见。您要在屏幕上滚动div吗?
Lekensteyn

什么样的重点?在浏览表单元素时是否具有相同的焦点?您唯一要做的就是显示该元素,如果该元素已经显示,则不起作用。
菲利克斯·克林

滚动查看时聚焦吗?
epascarello 2011年

Answers:


123

您可以使用锚点来“聚焦” div。即:

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

然后使用以下javascript:

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

9
Chrome(WebKit)有一个错误,该错误会导致在设置锚点后页面无法滚动。使用:location.href="#";location.href="#myDiv"。使用id="myDiv"是首选的,name="myDiv"并且也可以使用。
Lekensteyn

8
我遇到了这个确切的问题,但是WebKit的“修复”在FF 3.6.13中给我带来了问题。它可以在没有“#”行的情况下工作,但是如果添加它,它将转到“#”,并且永远不会尝试进入“ #myDiv”。我会坚持不带“#”的解决方案,这对我有用...呜呼!
TimFoolery 2011年

1
这对我来说效果不佳,因为它会将所有这些导航事件添加到浏览器历史记录中,而且我无法轻松返回上一页
bikeman868

我认为下面的“ AnhSirk Dasarp”是将所需元素滚动到可见屏幕顶部的更好方法。
Curious101 '19

如果滚动条位于内部div中怎么办?
前千

241

scrollIntoView运作良好:

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

MDN文档中的完整参考:https :
//developer.mozilla.org/zh-CN/docs/Web/API/Element.scrollIntoView


11
@CameronMcCluskie只有怪异的“ scrollIntoViewOptions”(平滑滚动等)才具有独家的Firefox支持。我在答案中使用的基本用法应该适用于几乎所有内容。
schpet

4
我确认,从4月16日开始,它也可以在Opera和Chrome下运行。
lvr123 '16

2
使用此解决方案时,顶部有一个固定的导航栏,您也需要考虑这一点。其他解决方案可能更适合,例如带有正确计算的posY的windows.scrollTo(posX,posY)。
曼弗雷德

2
在Firefox,Opera和Safari中工作。
Jagdeep Singh'9

3
这是与浏览器兼容的另一个来源(犬)scrollIntoView
The Red

99

您的问题和答案看起来不同。我不知道我是否记错了,但是对于那些用谷歌搜索并到达此处的人,我的答案是:

  1. 我对stackoverflow的回答
  2. 一个类似的问题

我的回答说明:

这是一个简单的JavaScript

当您需要滚动屏幕到具有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];
    }
}

屏幕将滚动到您的特定元素。


12
该解决方案的优点是,通过添加MyID锚点,不会弄乱浏览器导航栏中的可见URL。
Renaud Bompuis

2
谢谢,我觉得这应该是可以接受的答案,因为它是Java脚本,而不是HTML,而不是当前答案对我不起作用,但这确实可以!
史蒂夫·伯恩

也就是说,如果window要滚动,则不要滚动查看区域
WebWanderer

1
更改[curtop]curtop结尾后即可工作
goldylucks

如果您不希望它将此元素推到页面的最顶端,而是希望它滚动以使该元素位于屏幕的中心,请(window.screen.height/2)从findPos中减去
Albert Renshaw

47

对于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上受支持)。您很可能(未测试)通过了选项而没有任何副作用。

当然,这些可以包装在一个函数中,该函数的行为取决于所使用的浏览器。


3
像魅力一样工作:)
Midzer

1
这是唯一适用于Chrome的解决方案。
wkille

1
我想采用您的解决方案,因为可以微调位置(在我的情况下为y-80)。好像是var element = document.getElementById(“ Div”); 您的示例中缺少?此外,它不适用于IE11。IE11不知道window.scrollY-我们必须使用window.pageYOffset来接收值。更改后,我遇到了各种(不理解)jquery错误(当然,大多数情况下-仅在IE11中。因此,我实现了document.getElementById(“ divFirst”)。scrollIntoView();然后实现了$(window ).scrollTop($(window).scrollTop()-80);适用于所有浏览器
FredyWenger

Safari不支持(将选项传递给window.scroll
goldylucks

感谢您的评论,我更新了答案以包括浏览器兼容性。
穴居人

8

试试这个:

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

例如@:

http://jsfiddle.net/Vgrey/


我只想强调DOM属性是element.tabIndex但不是element.tabindex;第二个可以在Firefox上运行,但不能在Chrome上运行(至少在我前一段时间尝试过的时候)。当然,作为一个HTML属性都tabIndextabindex工作(和XHTML,tabindex必须使用)
奥里奥尔

6

要滚动到给定的元素,只需在下面制作此仅适用于javascript的解决方案即可。

简单用法:

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

@codeWithMe Yap,它更像是一个类似于iOS的代码,实际数量无关紧要,因此您可以继续按照其功能/包含的内容进行命名。我更喜欢这种短裤。
杰里·博尔巴斯(GeriBorbás)

5

这是一个可以为这些固定标头包含可选偏移量的函数。无需外部库。

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)

5

您可以将焦点设置为element。它比scrollIntoView

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

node.focus()

node.removeAttribute('tabindex')


哦,老兄,你救了我的日子。测试了很多东西,但这是唯一对我有用的东西,它支持所有浏览器。顺便说一句,我创建了一个输入,并给出了1px的高度和宽度,并专注于输入。它的效果很好。谢谢
Martian.titan

5

最佳,最短的答案即使对动画效果也有效:

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

如果您有固定的导航栏,只需从顶部值减去它的高度,所以如果您固定的导航栏高度为70px,则第2行将如下所示:

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

说明: 第1行获得元素位置第2行滚动到元素位置;behavior属性添加了平滑的动画效果


真的很酷,但尚未在Safari和其他一些浏览器上运行。确实可以与此polyfill github.com/iamdustan/smoothscroll一起使用。;)
ÍhorMé19'Nov

2

焦点只能设置在交互式元素上。Div仅代表页面的逻辑部分。

也许您可以在div周围设置边框或更改其颜色以模拟焦点。是的,可见性不是重点。


1

我认为,如果将tabindex添加到div中,它将能够获得焦点:

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

我不认为这是有效的,tabindex只能应用于a,区域,按钮,输入,对象,选择和textarea。但是尝试一下。


1
HTML5中tabindex有一个“核心属性”,是“全局属性”(HTML语言中所有元素共有的属性)。参见w3.org/TR/2011/WD-html-markup-20110113/global-attributes.html
Oriol

1

类似于@caveman的解决方案

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

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


0

经过一番环顾后,这终于对我有用:

  1. 在具有滚动条的dom中查找/定位div。对我来说,它看起来像这样:“ div class =” table_body table_body_div“ scroll_top =” 0“ scroll_left =” 0“ style =” width:1263px; 高度:499像素;”

  2. 我通过以下xpath找到了它:// div [@ class ='table_body table_body_div']

  3. 使用JavaScript执行这样的滚动:(JavascriptExecutor)驱动程序).executeScript(“ arguments [0] .scrollLeft = arguments [1];”,element,2000);

2000是我想向右滚动的像素数。如果要向下滚动div,请使用scrollTop而不是scrollLeft。

注意:我尝试使用scrollIntoView,但由于我的网页有多个div,因此无法正常工作。如果只有一个主窗口位于焦点上,它将起作用。如果您不想使用我不想使用的jQuery,这是我遇到的最好的解决方案。


0

我经常使用的一种方法来将容器滚动到其内容。

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

如果您希望全局覆盖,也可以执行以下操作:

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

0

由于行为原因,“平滑”在Safari,Safari ios,Explorer中不起作用。我通常使用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)
    })
  }

})();

-1

如果您想使用html,可以使用以下代码:

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

并使其成为指向特定元素ID的html链接。它基本上是getElementByIdhtml版本。


-3

试试这个功能

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

将div id作为参数传递,它将可以使用,我已经在使用它了


什么图书馆是$j
EoghanM

我假设$ j引用jQuery-问题表明它需要Javascript。
卡梅伦W.17年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.