从不同的页面使用jQuery滚动到ID

51

我尝试在一些页面中使用jQuery的页面滚动功能,并且成功地实现了平滑的页面滚动。但唯一的问题是,在尝试从不同的页面进行滚动时出现了问题。我的意思是,如果我在页面上点击链接,它应该加载新页面,然后滚动到特定的div元素。

这是我用于在页面内滚动的代码:

var jump=function(e)
{
       //prevent the "normal" behaviour which would be a "hard" jump
       e.preventDefault();
   //Get the target
   var target = $(this).attr("href");
   //perform animated scrolling
   $('html,body').animate(
   {
           //get top-position of target-element and set it as scroll target
           scrollTop: $(target).offset().top
   //scrolldelay: 2 seconds
   },2000,function()
   {
           //attach the hash (#jumptarget) to the pageurl
           location.hash = target;
   });

}

$(document).ready(function()
{
       $('a[href*=#]').bind("click", jump);
       return false;
});

我希望这个想法清楚明了。

谢谢

非常重要的提示: 我上面发布的代码可以在同一页内很好地工作,但我想要的是从一个页面点击链接并转到另一个页面,然后滚动到目标位置。我希望现在清楚了。谢谢


基本上的想法是使用Ajax加载页面,然后平滑地滚动到目标位置,就像你可以在acko.net上浏览页面一样。 - sg3s
是的,类似这样,但不要在点击按钮之前加载页面。意思是先点击URL移动到另一个页面,然后在页面加载后滚动到div元素。看起来好像已经有人回答了。 - Digital site
7个回答

66

你需要执行以下操作:

  • 将目标哈希值包含在指向其他页面的链接中 (href="other_page.html#section")
  • 在你的 ready 处理程序中,清除由哈希值指定的强制跳转滚动,尽快将页面滚动回到顶部并调用 jump() - 你需要异步执行此操作
  • jump() 中,如果没有传递事件,则将 location.hash 设置为目标哈希值
  • 此技术可能无法及时捕获跳转,因此最好立即隐藏 html,body 并在将其滚动回零后再显示它们

这是你原来的代码,加上了以上内容:

var jump=function(e)
{
   if (e){
       e.preventDefault();
       var target = $(this).attr("href");
   }else{
       var target = location.hash;
   }

   $('html,body').animate(
   {
       scrollTop: $(target).offset().top
   },2000,function()
   {
       location.hash = target;
   });

}

$('html, body').hide();

$(document).ready(function()
{
    $('a[href^=#]').bind("click", jump);

    if (location.hash){
        setTimeout(function(){
            $('html, body').scrollTop(0).show();
            jump();
        }, 0);
    }else{
        $('html, body').show();
    }
});

已验证在Chrome / Safari,Firefox和Opera中工作。但我不知道IE的情况。


3
我已经将工作示例放到了网上:http://vostrel.cz/so/9652944/page.html。另外,我注意到上面的脚本没有显示没有哈希的隐藏正文。通过在`.ready()`条件中添加`else`子句进行修复。 - Petr Vostrel
2
谢谢,伙计。那是一个绝妙的解决方案。这正是我想要的。现在我可以自己添加任何效果了。你先得到了赏金分,而且你应该得到它。 - Digital site
2
很奇怪,当我尝试使用这段代码时,整个页面都消失了? - Dikeneko
1
@PetrVostrel 对我来说,你的链接在跳转到第二页时没有动画滚动。它立即跳转到ID... 它对你实际上起作用了吗? - trainoasis
1
是的,对我也不起作用 - 如果有很多内容,它会使页面闪烁,但最终只到达目标... - Julix
显示剩余3条评论

26
在链接中加入一个井号:
<a href="otherpage.html#elementID">Jump</a>

并且在另一个页面上,你可以这样做:

$('html,body').animate({
  scrollTop: $(window.location.hash).offset().top
});

在其他页面上,您应该有一个id设置为elementID的元素以便滚动到它。当然,您可以更改其名称。


谢谢你的回答。我会尝试并在完成后提供一些反馈。再次感谢。 - Digital site
我尝试过,但没成功。我猜可能是我漏了什么或者有一些不正确的地方。我在 a href 链接上做了一个哈希,但仍然不确定其他代码应该放在哪里。结果是当我点击链接时,它直接跳转到页面上的 div,而没有平滑地滚动到那个位置,这很奇怪。我相信代码与此有关,所以平滑滚动起作用...你有什么好的解决方法吗? - Digital site
谢谢大家的回复。我会在手头的事情完成后查看你们所有的答案。 - Digital site
这对我有效。我为需要它的人进行注释。 - Alberto Rubio
@Sarfraz 如果可能的话,您能否检查一下这个问题:https://stackoverflow.com/questions/56430914/the-section-heading-is-hiding-while-using-smooth-scroll-from-one-page-to-another - questionbank
这是简短而精炼的解决方案。为了使滚动条平滑出现,您只需将毫秒数添加到animate()方法中。<script> $(document).ready(function(){ $('html,body').animate({ scrollTop: $(window.location.hash).offset().top - $('#header').height() }, 1000); }); </script> - Ron16

11

结合Petr和Sarfraz的回答,我得出以下结论。

在page1.html页面上:

<a href="page2.html#elementID">Jump</a>

在 page2.html 页面上:

<script type="text/javascript">
    $(document).ready(function() {
        $('html, body').hide();

        if (window.location.hash) {
            setTimeout(function() {
                $('html, body').scrollTop(0).show();
                $('html, body').animate({
                    scrollTop: $(window.location.hash).offset().top
                    }, 1000)
            }, 0);
        }
        else {
            $('html, body').show();
        }
    });
</script>

6
我建议使用scrollTo插件,http://demos.flesler.com/jquery/scrollTo/。你可以通过jquery css选择器设置scrollto。
$('html,body').scrollTo( $(target), 800 );

我使用这个插件和它的方法,取得了很好的准确性,而用其他实现同样效果的方法,如使用.offset().position()在过去对于我来说在跨浏览器方面都失败了。并不是说你不能使用这样的方法,我相信有一种在跨浏览器方面实现它的方法,但我发现scrollTo更可靠。


谢谢你的回答。我知道这个解决方案,据我回忆,它是用于页面内滚动,而不是从一个页面到另一个页面,然后滚动到目标位置。不好意思,但还是谢谢你的尝试。 - Digital site
只能在文档或文档元素内滚动,我不再理解您所说的“页面”是什么意思。您无法滚动到另一个文档。 - Fresheyeball
可能有点混乱。当您在页面A上单击链接以转到页面B,然后向下滚动到div元素时。这就是我想要实现的,但没关系,解决方案已经在那里了。感谢您的尝试。 - Digital site
2
是的,我的解决方案可以做到。不过不用担心,选择适合您的答案即可。 - Fresheyeball
我知道这已经过时了,但它不再是使用插件来滚动的首选。 - Akyl
我不熟悉scroll.local。 - Fresheyeball

2
我制作了一个可重用的插件,可以做到这一点...我将事件绑定留给了插件之外,因为我觉得对于这样一个小助手来说过于侵入性了...
jQuery(function ($) {

    /**
     * This small plugin will scrollTo a target, smoothly
     *
     * First argument = time to scroll to the target
     * Second argument = set the hash in the current url yes or no
     */
    $.fn.smoothScroll = function(t, setHash) {
        // Set time to t variable to if undefined 500 for 500ms transition
        t = t || 500;
        setHash = (typeof setHash == 'undefined') ? true : setHash;

        // Return this as a proper jQuery plugin should
        return this.each(function() {
            $('html, body').animate({
                scrollTop: $(this).offset().top
            }, t);

            // Lets set the hash to the current ID since if an event was prevented this doesn't get done
            if (this.id && setHash) {
                window.location.hash = this.id;
            }
        });
    };

});

现在,接下来,我们可以在onload中执行以下操作:检查哈希值,如果存在,则尝试直接将其用作jQuery选择器。此时我无法轻易测试此功能,但不久前我为生产站点制作了类似的内容,如果此方法不能立即奏效,请告诉我,我会研究我得到的解决方案。(脚本应该在onload部分中)
if (window.location.hash) {
    window.scrollTo(0,0);
    $(window.location.hash).smoothScroll();
}

下一步,我们将插件绑定到只包含哈希的锚点的onclick事件上。 (脚本应该在onload部分内)
$('a[href^="#"]').click(function(e) {
    e.preventDefault();

    $($(this).attr('href')).smoothScroll();
});

由于jQuery如果匹配失败就不会执行任何操作,因此当页面上的目标无法找到时,我们有一个很好的备用方案。

更新

当只有一个哈希标记时,替代的onclick处理程序可以滚动到顶部:

$('a[href^="#"]').click(function(e) {
    e.preventDefault();
    var href = $(this).attr('href');

    // In this case we have only a hash, so maybe we want to scroll to the top of the page?
    if(href.length === 1) { href = 'body' }

    $(href).smoothScroll();
});

这里还有一个简单的jsfiddle,演示了页面内滚动,onload有点难设置... http://jsfiddle.net/sg3s/bZnWN/ 更新2
所以你可能会因为窗口已经在加载时滚动到元素而遇到问题。这可以解决:window.scrollTo(0,0); 它只是将页面滚动到左上角。将其添加到上面的代码片段中。

感谢您的回答。代码很好,但无法从一个页面使用到另一个页面,然后滚动到目标位置。再次感谢您的努力。 - Digital site
如果是这样,你的想法对我们所有人来说都不清楚... 如果你能明确问题,我愿意再试一次 :| - sg3s
谢谢,但我完全没有问题听取任何答案。如果悬赏积分过期了,我会重新设置新的,因为这个问题对我很重要。再次感谢。 - Digital site

2
function scroll_down(){
    $.noConflict();
    jQuery(document).ready(function($) {
        $('html, body').animate({
            scrollTop : $("#bottom").offset().top
        }, 1);
    });
    return false;
}

这里的“bottom”是您想要滚动到的div标签id。要更改动画效果,您可以将时间从“1”更改为其他值。


感谢@vijayrk的答案。这段代码也是用于页面内滚动,而不是从一个页面到另一个页面来滚动目标。 - Digital site
那么这是否意味着您想在父页面中编写jQuery代码,以便效果在子页面上发生?也就是说,在pageA页面中有一个指向pageB页面的链接。PageB页面有一个名为“abc”的div元素。所以这是否意味着您想在PageA页面中编写jQuery代码,以便当您点击PageB链接时,页面会跳转到PageB并滚动到id为"abc"的div元素位置? - user1284907
不是特别的,伙计。在A页面中我有一个指向B页面的链接。当我点击那个链接时,我就会进入B页面并滚动到C元素所在的位置... - Digital site

0

我写了一个程序,用于检测页面是否包含所点击的锚点,如果没有,则跳转到正常页面,否则滚动到特定的部分:

$('a[href*=\\#]').on('click',function(e) {

    var target = this.hash;
    var $target = $(target);
    console.log(targetname);
    var targetname = target.slice(1, target.length);

    if(document.getElementById(targetname) != null) {
         e.preventDefault();
    }
    $('html, body').stop().animate({
        'scrollTop': $target.offset().top-120 //or the height of your fixed navigation 

    }, 900, 'swing', function () {
        window.location.hash = target;
  });
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接