如何在加载页面时禁用锚点跳转?

123

我认为这可能是不可能的,我会尽力解释清楚。

我有一个包含选项卡(使用jQuery控制)的页面,由以下代码控制:

我正在使用由另一个用户在以前的问题中提供的代码。

<script type="text/javascript">
    $(function() {

     $('html, body').animate({scrollTop:0}); // this is my "fix"

        var tabContent = $(".tab_content");
        var tabs = $("#menu li");
        var hash = window.location.hash;
     tabContent.not(hash).hide();
        if(hash=="") {
      $('#tab1').fadeIn();
     }
        tabs.find('[href=' + hash + ']').parent().addClass('active');

        tabs.click(function() {
            $(this).addClass('active').siblings().removeClass('active');
            tabContent.hide();
            var activeTab = $(this).find("a").attr("href");

            $(activeTab).fadeIn();
           return false;
        });

    });
</script>

当我直接访问“标签”页面时,这段代码效果很好。

然而,我需要从其他页面链接到单独的标签 - 为此,该代码获取window.location.hash,然后显示相应的标签。

由于有“return false”,所以页面不会因为锚点而“跳转”。

只有在点击事件触发时才会触发此事件。因此,如果我从其他任何页面访问我的“标签”,将会触发“跳转”效果。为了解决这个问题,我自动滚动到页面顶部,但我宁愿不要发生这种情况。

是否有任何办法在页面加载时模拟“return false”,防止出现锚点“跳转”?

希望这足够清楚。

谢谢

16个回答

1

这将适用于Bootstrap v3

$(document).ready(function() {
  if ($('.nav-tabs').length) {
    var hash = window.location.hash;
    var hashEl = $('ul.nav a[href="' + hash + '"]');
    hash && hashEl.tab('show');

    $('.nav-tabs a').click(function(e) {
      e.preventDefault();
      $(this).tab('show');
      window.location.hash = this.hash;
    });

    // Change tab on hashchange
    window.addEventListener('hashchange', function() {
      var changedHash = window.location.hash;
      changedHash && $('ul.nav a[href="' + changedHash + '"]').tab('show');
    }, false);
  }
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
<div class="container">
<ul class="nav nav-tabs">
  <li class="active"><a data-toggle="tab" href="#home">Home</a></li>
  <li><a data-toggle="tab" href="#menu1">Menu 1</a></li>
</ul>

<div class="tab-content">
  <div id="home" class="tab-pane fade in active">
    <h3>HOME</h3>
    <p>Some content.</p>
  </div>
  <div id="menu1" class="tab-pane fade">
    <h3>Menu 1</h3>
    <p>Some content in menu 1.</p>
  </div>
</div>
</div>


0

通过这样做解决了我的问题:

// navbar height 
var navHeigth = $('nav.navbar').height();    

// Scroll to anchor function
var scrollToAnchor = function(hash) {
  // If got a hash
  if (hash) {
    // Scroll to the top (prevention for Chrome)
    window.scrollTo(0, 0);
    // Anchor element
    var term = $(hash);

    // If element with hash id is defined
    if (term) {

      // Get top offset, including header height
      var scrollto = term.offset().top - navHeigth;

      // Capture id value
      var id = term.attr('id');
      // Capture name value
      var name = term.attr('name');

      // Remove attributes for FF scroll prevention
      term.removeAttr('id').removeAttr('name');
      // Scroll to element
      $('html, body').animate({scrollTop:scrollto}, 0);

      // Returning id and name after .5sec for the next scroll
      setTimeout(function() {
        term.attr('id', id).attr('name', name);
      }, 500);
    }
  }
};

// if we are opening the page by url
if (location.hash) {
  scrollToAnchor(location.hash);
}

// preventing default click on links with an anchor
$('a[href*="#"]').click(function(e) {
  e.preventDefault();
  // hash value
  var hash = this.href.substr(this.href.indexOf("#"));
  scrollToAnchor(hash);
});`

0

另一种方法

尝试检查页面是否已滚动,然后再重置位置:

var scrolled = false;

$(window).scroll(function(){
  scrolled = true;
});

if ( window.location.hash && scrolled ) {
  $(window).scrollTop( 0 );
}

这里是演示


不工作兄弟...初始加载在底部...刷新后它停留在顶部。 - Martin Zvarík

0

我曾尝试在Firefox中使用以上的setTimeout方法,但并没有取得很好的效果。

于是,我使用了一个onload函数来代替setTimeout:

window.onload = function () {
    if (location.hash) {
        window.scrollTo(0, 0);
    }
};

很不幸,它仍然存在很多故障。


因为onload在所有内容都完全加载完成后运行,包括照片...所以这种方式肯定会出现故障。 - Martin Zvarík

0

尝试在事件处理程序中使用以下代码来防止客户端发生任何垂直滚动:

var sct = document.body.scrollTop;
document.location.hash = '#next'; // or other manipulation
document.body.scrollTop = sct;

(浏览器重绘)


0

我在这些解决方案中没有取得任何持续的成功。

显然是因为跳转发生在Javascript之前 => reference(http://forum.jquery.com/topic/preventing-anchor-jump)

我的解决方案是使用CSS将所有锚点默认定位在顶部。

.scroll-target{position:fixed;top:0;left:0;}

然后使用jquery滚动到目标锚点的父级,或者是一个兄弟元素(可能是一个空的em标签)。
<a class="scroll-target" name="section3"></a><em>&nbsp</em>

当输入带有哈希的URL时,使用jQuery示例进行滚动
(页面不能已经加载在窗口/选项卡中,这涵盖了来自其他/外部来源的链接)

setTimeout(function() {
    if (window.location.hash) {               
        var hash = window.location.hash.substr(1);   
        var scrollPos = $('.scroll-target[name="'+hash+'"]').siblings('em').offset().top; 
        $("html, body").animate({ scrollTop: scrollPos }, 1000);    
    }
}, 1);

此外,您需要在页面上防止默认的锚点点击事件,并滚动到它们的目标位置。

<a class="scroll-to" href="#section3">section three</a>

和 jQuery

$('a.scroll-to').click(function(){
    var target = $(this).attr('href').substr(1);
    var scrollPos = $('.scroll-target[name="'+target+'"]').siblings('em').offset().top; 
    $("html, body").animate({ scrollTop: scrollPos }, 1000);
    return false;
});

这种方法的好处是锚点标签与相关内容在结构上保持一致,尽管它们的CSS位置在顶部。

这意味着搜索引擎爬虫不会有问题。

祝好,希望这有所帮助
Gray


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