Как отключить якорный «прыжок» при загрузке страницы? - PullRequest
98 голосов
/ 07 сентября 2010

Я думаю, что это не возможно, постараюсь объяснить как можно лучше.У меня есть страница, содержащая вкладки (с поддержкой 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».

однако это событие вызывается только при событии щелчка.следовательно, если я захожу на мои «вкладки» с любой другой страницы, срабатывает эффект «прыжка».Чтобы бороться с этим, я автоматически прокручиваю до верхней части страницы, но я бы предпочел, чтобы этого не произошло.

есть ли способ имитировать «возврат ложного» при загрузке страницы, предотвращая «прыжок» привязкиот происходящего.

надеюсь, что это достаточно ясно.

спасибо

Ответы [ 16 ]

0 голосов
/ 07 февраля 2019

Это будет работать с 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 голосов
/ 14 июля 2016

Решил мою проблему следующим образом:

// 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 голосов
/ 17 декабря 2014

Попробуйте, чтобы предотвратить любую вертикальную прокрутку клиента на хеш-коде (внутри вашего обработчика событий):

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

(перерисовка браузера)

0 голосов
/ 30 ноября 2013

У меня не было последовательного успеха с этими решениями.

Видимо из-за того, что скачок происходит раньше, чем Javascript => ссылка (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>

Пример jquery для прокрутки, когда URL вводится с помощью хеша
(страница не должна быть уже загружена в окно / вкладку, это относится к ссылкам из других / внешних источников)

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-позиция находится сверху.

Это должно означать, что сканеры поисковых систем не будут иметь проблем.

Ура, я надеюсь, что это помогает
Серый

0 голосов
/ 27 сентября 2013

У меня не было большого успеха с вышеуказанными setTimeout методами в Firefox.

Вместо setTimeout я использовал функцию загрузки:

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

К сожалению, все еще очень глючно.

0 голосов
/ 16 мая 2013

Другой подход

Попробуйте проверить, была ли страница прокручена, и только затем сбросьте позицию:

var scrolled = false;

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

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

Вот демо

...