如何在执行jquery事件后保持页面滚动位置不变?

41

我已经寻找了各种答案,找到了类似的问题,但这些答案并不适用于我的情况。事实上,我很新手,所以我没有能力将找到的答案应用到我的问题上。

问题是:

我有一个 Div,当缩略图被点击时,Div 图像通过 JavaScript/jQuery 脚本替换为另一张图片(我不确定确切的方式,也许有人可以澄清)。这个功能正常工作,但问题在于页面会回滚到顶部,用户必须再次向下滚动才能看到替换后的图片。

我在网上查找了一些资料,发现在 JavaScript 中添加“return false”语句可能有帮助,但我已经查看过代码,并发现“return false”已经存在。

另一个选择是使用基于 JavaScript cookie 的解决方案,在其中发送一个 cookie,并通过读取 cookie 来保持浏览器滚动位置,然而我好像无法让这个解决方案起作用,我认为这个问题可能是由于我正在本地托管造成的,但我也可能错了……

第三个选择是使用 PHP 脚本,但我没有找到明确的答案,并且这意味着我将不得不学习 PHP(这是我以后肯定要学习的东西)。

以下是 JavaScript 代码:

<script type="text/javascript">

 $(document).ready(function() {
  $('.galleryicon').live("click", function() {

    $('#mainImage').hide();
    $('#cakebox').css('background-image', "url('ajax-loader.gif')");
    var i = $('<img />').attr('src',this.href).load(function() {
        $('#mainImage').attr('src', i.attr('src'));
        $('#cakebox').css('background-image', 'none');
        $('#mainImage').fadeIn();
    });
    return false; 
   });
 });

</script>

这是HTML代码:

<div class="cakecont">

  <div id="cakebox">

 <img src="../images/cakes/babycake1.png" alt="Main Image" id="mainImage"/>

     <div class="pageinfo2">
     <h3>Cake Type 1</h3>
     <h6>£2.00</h6>
     </div>
     <div class="infobox">
     <h6> Description </h6>
     </div> 

      <div class="gallerybox">
      <a href="../images/cakes/babycaketop.png" class="galleryicon">
      <img src="../images/thumbs/babycaketopsml.png" alt="Thumbnail 2"/></a>

      <a href="../images/cakes/babycake1.png" class="galleryicon">
      <img src="../images/thumbs/babycakesml.png" alt="Image 1"/></a>
   </div>
  </div>
</div>

这是一个工作演示链接 http://micahcarrick.com/code/jquery-image-swap/index.html

我已尝试自行解决这个问题。这是我在建立网站过程中第一个需要提问的问题,所有之前遇到的问题都是通过谷歌解决的,但这个问题超出了我的搜索引擎技能。

以下是该页面的所有HTML代码,以防其他脚本覆盖了“新”修改后的JavaScript代码:

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org     /TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml"><head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Cupcakes &amp; Cakes for Birthday/Wedding Gift in Bournemouth Dorset - SweetVision</title>
   <meta name="keywords" content="cupcakes, cake, gift, wedding, birthday, Bournemouth, Dorset" />
 <meta name="description" content="For the finest Cupcakes and Cakes in Bournemouth Dorset look no further, Sweetvision specialise in baked goods for Weddings, Birthdays, Baby Showers, Easter, Halloween, Christmas" />
 <meta name="robots" content="ALL" />
 <meta http-equiv= "Content-Language" content="en" />
 <meta name="Publisher" content="Sweet Vision" />
 <meta name="Copyright" content="Copyright 2012, Sweet Vision, All rights reserved." />
 <meta name="Author" content="Mark Webb for Sweet Vision - www.sweetvision.co.uk" />

  <link href="../images/homepage/favicon.ico" type="image/vnd.microsoft.icon" rel="shortcut icon" />

  <link href="../root/css/sweetvision.css" rel="stylesheet" type="text/css" />

  <script src="../js/jquery-1.4.2.min.js" type="text/javascript"></script>

  <script type="text/javascript">

 $(document).ready(function() {   
$('.galleryicon').live("click", function(e) {  // the (e) represent the event
$('#mainImage').hide();     
$('#cakebox').css('background-image', "url('ajax-loader.gif')");     
var i = $('<img />').attr('src',this.href).load(function() {         
  $('#mainImage').attr('src', i.attr('src'));         
  $('#cakebox').css('background-image', 'none');         
  $('#mainImage').fadeIn();     
 });
 e.preventDefault(); //Prevent default click action which is causing the 
 return false;       //page to scroll back to the top
 });  
});


</script>

<script src="../js/s3Slider.js" type="text/javascript"></script> 

 <script type="text/javascript">

 $(document).ready(function() {
 $('#s3slider').s3Slider({
  timeOut: 4000
  });
}); 
  </script>

  <script src="../js/SpryMenuBar.js" type="text/javascript"></script>
  <link href="../root/css/SpryMenuBarHorizontal.css" rel="stylesheet" type="text/css" />

  </head> 


 <body>



  <div class="container">


 <div class="sprybox">
   <ul id="check_menu" class="MenuBarHorizontal">
    <li><a href="../root/index.html">Home</a></li>
    <li><a href="../root/aboutus.html" class="MenuBarItemSubmenu">About Us</a>
      <ul>
        <li><a href="../root/contactus.html">Contact</a></li>
        <li><a href="../root/news.html">News</a></li>
        <li><a href="../root/events.html">Events</a></li>
      </ul>
    </li>
       <li><a href="../root/ourmenu.html">Our Menu</a></li>
         <li><a href="gallery.html">Gallery</a></li>
          </ul>
        <div class="mainmenu">
           <a href="../root/mainmenu.html">
           <img src="../images/buttons/mainmenu.png" />
           </a>
       </div>
        <div class="backbutton">
        <a href="javascript:history.go(-1)"> 
        <img src="../images/buttons/Backbutton.png" /></a>
      </div>

    </div>  <!-- end.header --><!--end of sprybox -->

  <!--end div element -->


 <!-- thumbnails are links to the full size image -->

  <div class="cakecont">

 <div id="cakebox">

  <img src="../images/cakes/babycake1.png" alt="Main Image" id="mainImage"/>

     <div class="pageinfo2">
     <h3>Cake Type 1</h3>
     <h6>£2.00</h6>
     </div>
     <div class="infobox">
     <h6> Description </h6>
     </div> 

 <div class="gallerybox">
      <a href="../images/cakes/babycaketop.png" class="galleryicon">
      <img src="../images/thumbs/babycaketopsml.png" alt="Thumbnail 2"/></a>

      <a href="../images/cakes/babycake1.png" class="galleryicon">
      <img src="../images/thumbs/babycakesml.png" alt="Image 1"/></a>
  </div>
  </div>
</div>



 <div class="footer">
  <p>Copyright &copy; 2012 by Mark Webb. All rights reserved.</p>
 </div> <!-- end .footer -->

</div> <!-- end .container -->


 <script type="text/javascript">
 var MenuBar1 = new Spry.Widget.MenuBar("check_menu",{imgDown:"SpryAssets/SpryMenuBarDownHover.gif",   imgRight:"SpryAssets/SpryMenuBarRightHover.gif"});
  </script>

 <script type="text/javascript">

  var _gaq = _gaq || [];
 _gaq.push(['_setAccount', 'UA-29457683-1']);
  _gaq.push(['_trackPageview']);

   (function() {
  var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
  ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') +    '.google-analytics.com/ga.js';
  var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

 </script>


 </body>
</html>

当我访问该页面时,我没有看到任何滚动条。整个页面适合屏幕。您是否使用较小的分辨率? - kevin628
是的,我正在使用笔记本电脑,所以我可以获得滚动效果,谢谢。 - marky
7个回答

65

您可以保存当前的滚动位置,然后稍后再设置回来:

var tempScrollTop = $(window).scrollTop();

..//Your code

$(window).scrollTop(tempScrollTop);

谢谢你的回答,但我不确定在哪里应用你的代码,我对Javascript了解甚少。 - marky
对于每一次点击,你希望在执行任何操作之前保存滚动位置,并在所有操作完成后恢复它。因此,你需要将第一行放在你的点击函数开头,将最后一行放在它结束之前(在return语句之前)。 - Briguy37
@user1428659:嗯,我再次查看了您的代码,可能不起作用,因为它似乎是异步的(fadeIn在恢复滚动之前没有被调用)。因此,如果这对您不起作用,请在fadeIn()之后放置第二行。另外,如果您知道图像的高度,可以将图像标记包装在一个始终显示的空白div中,以防止其一开始就滚动。 - Briguy37

36

如果你从Google过来,正在使用锚点元素来触发事件,请确保同样避免点击:

<a  
href='javascript:void(0)'  
onclick='javascript:whatever causing the page to scroll to the top'  
></a>

2
非常感谢,我正努力阻止在一个 $('form').submit(function{}); 中滚动的行为,使用 e.preventDefault();。即使我在返回之前放置了 $(window).scrollTop(tempScrollTop);,或者即使我返回了它,它仍然会回到顶部。这对我起作用。 - KacieHouser
2
@Akeel 我认为使用类似 href="#" 的东西会应用默认操作到浏览器,导致它滚动到顶部(重定向到 http..../#)。如果你使用 Nasser Al-Wohaibi 建议的方法或类似这样的方法:
  • 在你的点击处理程序底部放置 return false;,那么 href 就不会被跟踪。
  • 在你的处理程序中调用事件的 preventDefault 方法:
function( e ) { e.preventDefault(); // 你的事件处理代码 }你可以强制浏览器不执行默认操作。
- Diamantatos Paraskevas
太好了。我在使用SignaturePad画布控件时遇到了一个问题,当单击清除锚点时,它会将滚动位置设置为顶部。这个解决方案完美地解决了我的问题! - Mkalafut

7
尝试使用下面的代码来阻止默认行为,使页面不会滚动回到页面顶部。
$(document).ready(function() {   
  $('.galleryicon').live("click", function(e) {  // the (e) represent the event
    $('#mainImage').hide();     
    $('#cakebox').css('background-image', "url('ajax-loader.gif')");     
    var i = $('<img />').attr('src',this.href).load(function() {         
      $('#mainImage').attr('src', i.attr('src'));         
      $('#cakebox').css('background-image', 'none');         
      $('#mainImage').fadeIn();     
    });
  e.preventDefault(); //Prevent default click action which is causing the 
  return false;       //page to scroll back to the top
  });  
});

要了解有关event.preventDefault()的更多信息,请查看官方文档这里


非常感谢您的回答,我已经实现了代码,但它仍然跳转到页面顶部,我想知道是否有另一个脚本覆盖了它。 - marky
我刚刚制作了一个测试页面,你的解决方案似乎在页面滚动条不在底部时有效(即无法再滚动,因为没有更多内容)。 - marky
哎呀,按了回车键——但是如果滚动条在底部,页面会跳上1厘米。现在我刚刚试着给页面添加了一个高度为400像素的页脚,一旦点击缩略图,页面就会向上跳动约1厘米,但只要不滚动并再次点击另一个缩略图,页面就会保持静态。然而,如果您稍微滚动一下屏幕,然后再点击一个缩略图,页面将根据您向上或向下滚动来跳动—非常奇怪。感谢您的帮助。 - marky
我已经暂时解决了这个问题。在插入e.preventDefault()之后,我注意到页面会自动移动到缩略图div的底部边缘。为了解决这个问题,我将包含缩略图的div的高度扩展到了荒谬的程度(400px),现在当每个缩略图被点击时,页面不会滚动。为什么这样做有效呢? - marky
啊 - 现在在IE中它显示了一个向下延伸400像素的虚线框,所以我甚至无法将其修补... - marky

4
您想要做的就是防止点击事件的默认行为。为了实现这一点,您需要修改脚本,如下所示:
$(document).ready(function() {
  $('.galleryicon').live("click", function(e) {

    $('#mainImage').hide();
    $('#cakebox').css('background-image', "url('ajax-loader.gif')");
    var i = $('<img />').attr('src',this.href).load(function() {
        $('#mainImage').attr('src', i.attr('src'));
        $('#cakebox').css('background-image', 'none');
        $('#mainImage').fadeIn();
    });
    return false; 
    e.preventDefault();
   });
 });

所以,在这条语句中,你需要添加一个代表事件的“e”,语句为$('.galleryicon').live("click", function(e) {,并且你需要添加这一行e.preventDefault();


谢谢您的回答,但是如我所说,代码仍然会导致页面跳转到顶部 - 我想知道是否有其他东西覆盖了脚本。使用相同代码的演示网站也有相同的效果。如果您向下滚动页面,然后单击缩略图,页面将返回到顶部... 谢谢。 - marky
我已经暂时解决了这个问题。在插入e.preventDefault()之后,我发现页面会自动移动到缩略图div的底部边缘。为了修复这个问题,我将包含缩略图的div的高度扩展到荒谬的数值(400px),现在当点击每个缩略图时,页面不会滚动,为什么这样做有效呢? - marky

2

我曾遇到一个类似的问题,即在重新加载div内容后无法使用scrollTop。每次运行下面的程序时,内容都会滚动到顶部。我发现,在设置新的scrolltop之前稍微延迟一下可以解决这个问题。

这段代码摘自wdCalendar,我对这个过程进行了修改:

 function BuildDaysAndWeekView(startday, l, events, config)
   ....
        var scrollpos = $("#dvtec").scrollTop();
        gridcontainer.html(html.join(""));
        setTimeout(function() {
            $("#dvtec").scrollTop(scrollpos);
        }, 25);
   ....

没有延迟,就意味着它无法正常工作。


0
$('html,body').animate({
  scrollTop: $('#answer-<%= @answer.id %>').offset().top - 50
}, 700);

1
欢迎来到Stack Overflow!虽然这段代码可能是解决方案,但包括解释真的有助于提高您的帖子质量。请记住,您正在为未来的读者回答问题,而这些人可能不知道您的代码建议的原因。 - yivi

0

需要注意的是,在设置滚动位置时,请确保在正确的范围内进行。例如,如果您在多个函数中使用滚动位置,则应在这些函数之外设置它。

$(document).ready(function() {
    var tempScrollTop = $(window).scrollTop();
    function example() {
        console.log(tempScrollTop);
    };

});

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