Jak wyłączyć anchor "jump" podczas ładowania strony?

Myślę, że to może nie być możliwe, postaram się to wyjaśnić najlepiej jak potrafię. Mam stronę zawierającą zakładki (jQuery powered), kontrolowane przez:

Używam tego kodu, podanego przez innego użytkownika z poprzedniego pytania.

<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>

Ten kod działa świetnie, gdy odwiedzam stronę "karty" bezpośrednio.

Jednak muszę linkować do zakładek invidual z innych stron - aby to zrobić, kod dostaje window.location.hash, a następnie pokazuje zakładkę appropiate.

Strona nie "skok" do kotwicy z powodu "return false".

To zdarzenie jest jednak uruchamiane tylko w przypadku kliknięcia. stąd, jeśli odwiedzam moje "karty" z innej strony, efekt" skoku " jest wyzwalany. Aby to zwalczyć, automatycznie przewijam do góry strony, ale wolałbym, żeby tak się nie stało.

Czy istnieje sposób na symulację "return false" podczas ładowania strony, zapobiegając "skokowi" kotwicy.

Mam nadzieję, że to wystarczająco jasne.

Dzięki

Author: Rubens Mariuzzo, 2010-09-07

14 answers

Czy Twoja poprawka nie działa? Nie jestem pewien, czy dobrze rozumiem pytanie - Czy masz stronę demo? Można spróbować:

if (location.hash) {
  setTimeout(function() {

    window.scrollTo(0, 0);
  }, 1);
}

Edit: testowany i działa w Firefoksie, IE i Chrome na Windows.
Edit 2: Przesuń setTimeout() wewnątrz if bloku, props @vsync.

 129
Author: dave1010,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-10 08:07:09

Zobacz moją odpowiedź tutaj: odpowiedź Stackoverflow

Trik polega na tym, aby jak najszybciej usunąć hashtag i zapisać jego wartość na własny użytek:]}

Ważne jest, aby nie umieszczać tej części kodu w $ () lub $(window).load () działa tak, jak by było za późno, a przeglądarka już przeniosła się do tagu.

// store the hash (DON'T put this code inside the $() function, it has to be executed 
// right away before the browser can start scrolling!
var target = window.location.hash,
    target = target.replace('#', '');

// delete hash so the page won't scroll to it
window.location.hash = "";

// now whenever you are ready do whatever you want
// (in this case I use jQuery to scroll to the tag after the page has loaded)
$(window).on('load', function() {
    if (target) {
        $('html, body').animate({
            scrollTop: $("#" + target).offset().top
        }, 700, 'swing', function () {});
    }
});
 28
Author: Larzan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 11:55:53

Istnieją inne sposoby śledzenia karty, na której się znajdujesz; być może ustawianie pliku cookie lub wartości w ukrytym polu itp.

Powiedziałbym, że jeśli nie chcesz, aby Strona przeskakiwała przy ładowaniu, lepiej byłoby użyć jednej z tych innych opcji, a nie hash, ponieważ głównym powodem używania hasha w preferencjach do nich jest umożliwienie dokładnie tego, co chcesz zablokować.

Kolejny punkt - strona nie skoczy, jeśli twoje linki hashowe nie pasują do nazw tagów w dokument, więc być może, jeśli chcesz nadal używać hasha, możesz manipulować zawartością, aby znaczniki były inaczej nazwane. Jeśli użyjesz spójnego prefiksu, nadal będziesz mógł używać Javascript, aby przeskakiwać między nimi.

Mam nadzieję, że to pomoże.

 11
Author: Spudley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-07 13:43:18

Użyłem rozwiązania dave1010, ale było trochę nerwowe, gdy umieściłem je w $().funkcja ready. Więc zrobiłem to: (nie wewnątrz $().ready)

    if (location.hash) {               // do the test straight away
        window.scrollTo(0, 0);         // execute it straight away
        setTimeout(function() {
            window.scrollTo(0, 0);     // run it a bit later also for browser compatibility
        }, 1);
    }
 11
Author: lopsided,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-12 18:58:13
  1. Przeglądarka przeskakuje do <element id="abc" /> jeśli są http://site.com/#abc hash w adresie i element z id="abc" jest widoczny. Tak więc powinieneś domyślnie ukryć element: <element id="anchor" style="display: none" />. Jeśli na stronie nie ma widocznego elementu z id=hash, przeglądarka nie skoczy.

  2. Utwórz skrypt, który sprawdza hash w adresie url, a następnie wyszukuje i pokazuje element prrpopriate (który jest domyślnie ukryty).

  3. Wyłącz domyślne zachowanie "hash-like link" przez powiązanie zdarzenia onclick z dowiązaniem i określenie return false; jako wyniku zdarzenia onclick.

Kiedy zaimplementowałem tabs, napisałem coś takiego:

    <script>
    $(function () {         
        if (location.hash != "") {
            selectPersonalTab(location.hash);
        }
        else {
            selectPersonalTab("#cards");
        }
    });

    function selectPersonalTab(hash) {
        $("#personal li").removeClass("active");
        $("a[href$=" + hash + "]").closest("li").addClass("active");
        $("#personaldata > div").hide();
        location.hash = hash;
        $(hash).show();
    }

    $("#personal li a").click(function (e) {
        var t = e.target;
        if (t.href.indexOf("#") != -1) {
            var hash = t.href.substr(t.href.indexOf("#"));
            selectPersonalTab(hash);
            return false;
        }
    });
</script>
 8
Author: Sergei Smirnov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-30 14:59:03

Brudny CSS naprawia tylko, aby pozostać przewinięty za każdym razem, gdy używana jest kotwica (nie jest przydatny, jeśli nadal chcesz używać kotwic do skoków przewijania, bardzo przydatny do głębokiego linkowania):

.elementsWithAnchorIds::before {
   content: "";
   display: block;
   height: 9999px;
   margin-top: -9999px; //higher thin page height
}
 3
Author: anotheryou,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-23 17:31:32

Żadna z odpowiedzi nie działa mi wystarczająco dobrze, widzę, że strona przeskakuje do anchora, a następnie do góry dla niektórych rozwiązań, niektóre odpowiedzi w ogóle nie działają, mogą być rzeczy zmieniane przez lata. Mam nadzieję, że moja funkcja komuś pomoże.

/**
 * Prevent automatic scrolling of page to anchor by browser after loading of page.
 * Do not call this function in $(...) or $(window).on('load', ...),
 * it should be called earlier, as soon as possible.
 */
function preventAnchorScroll() {
    var scrollToTop = function () {
        $(window).scrollTop(0);
    };
    if (window.location.hash) {
        // handler is executed at most once
        $(window).one('scroll', scrollToTop);
    }

    // make sure to release scroll 1 second after document readiness
    // to avoid negative UX
    $(function () {
        setTimeout(
            function () {
                $(window).off('scroll', scrollToTop);
            },
            1000
        );
    });
}
 3
Author: kdmitry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-02 13:55:09

Chociaż zaakceptowana odpowiedź działa dobrze, zauważyłem, że czasami, szczególnie na stronach zawierających duże obrazy, które pasek przewijania będzie skakać dziko za pomocą

 window.scrollTo(0, 0);

Które mogą być dość rozpraszające dla użytkownika.

Rozwiązanie, które ostatecznie ustaliłem, jest całkiem proste i polega na użyciu innego identyfikatora na celu niż ten użyty w location.hash

Eg:

Oto link na innej stronie

<a href="/page/with/tabs#tab2">Some info found in tab2 on tabs page</a>

Więc oczywiście jeśli istnieje element z identyfikatorem tab2 na stronie tabs okno przeskoczy do niego po załadowaniu.

Więc możesz dodać coś do ID, aby temu zapobiec:

<div id="tab2-noScroll">tab2 content</div>

A następnie możesz dołączyć "-noScroll" do location.hash w javascript:

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

        var tabContent = $(".tab_content");
        var tabs = $("#menu li");
        var hash = window.location.hash;


     tabContent.not(hash + '-noScroll').hide();                           
        if(hash=="") {       //^ here
      $('#tab1-noScroll').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") + '-noScroll'; 
                                                               //^ and here

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

    });
</script>
 2
Author: andrew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-17 13:08:26

Myślę, że znalazłem sposób na karty UI bez ponownego wykonywania funkcji. Jak dotąd nie znalazłem żadnych problemów.

    $( ".tabs" ).tabs();
    $( ".tabs" ).not(".noHash").bind("tabsshow", function(event, ui) { 
        window.location.hash = "tab_"+ui.tab.hash.replace(/#/,"");
        return false;
    });

    var selectedTabHash = window.location.hash.replace(/tab_/,"");
    var index = $( ".tabs li a" ).index($(".tabs li a[href='"+selectedTabHash+"']"));
    $( ".tabs" ).not(".noHash").tabs('select', index);

Wszystko w ramach gotowego wydarzenia. Prepends "tab_" dla hasha, ale działa zarówno po kliknięciu, jak i stronie załadowanej Hashem.

 1
Author: JRomero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-09 14:23:55

Another approach

Spróbuj sprawdzić, czy strona została przewinięta i dopiero wtedy zresetuj pozycję:

var scrolled = false;

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

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

Heres a demo

 0
Author: hitautodestruct,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-16 15:14:28

Nie odniosłem większego sukcesu z powyższymi metodami setTimeout w Firefoksie.

Zamiast setTimeout, użyłem funkcji onload:

window.onload = function () {
    if (location.hash) {
        window.scrollTo(0, 0);
    }
};
Niestety nadal jest bardzo glitchery.
 0
Author: bozdoz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-27 19:38:06

Nie odniosłem żadnego konsekwentnego sukcesu z tymi rozwiązaniami.

Najwyraźniej ze względu na fakt, że skok odbywa się przed Javascript => reference ( http://forum.jquery.com/topic/preventing-anchor-jump )

Moim rozwiązaniem jest ustawienie wszystkich kotwic na górze domyślnie za pomocą CSS.

.scroll-target{position:fixed;top:0;left:0;}
Następnie użyj jquery, aby przewijać do rodzica docelowej kotwicy lub rodzeństwa(może pustego znacznika em)
<a class="scroll-target" name="section3"></a><em>&nbsp</em>

JQuery przykład przewijania po wpisaniu adresu URL z hash
(strona nie może być już załadowana w oknie / karcie, dotyczy to linków z innych / zewnętrznych źródeł)

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

Również będziesz chciał zapobiec domyślnym kliknięciom kotwicy na stronie, a następnie przewiń do ich celów

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

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

Dobrą rzeczą w tej metodzie jest to, że cele znaczników kotwicy pozostają strukturalnie obok odpowiedniej zawartości, chociaż ich pozycja CSS jest na górze.

Powinno to oznaczać, że crawlery wyszukiwarek nie będą miały problem.

Zdrówko, mam nadzieję, że to pomoże
Gray

 0
Author: grayskale.com,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-29 21:48:24

Spróbuj tego, aby uniemożliwić klientowi wszelkiego rodzaju przewijanie w pionie na hashchanged (wewnątrz obsługi zdarzenia):

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

(przeglądarka przerysowana)

 0
Author: andy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-17 19:23:03

Rozwiązałem mój promem robiąc to:

// 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
Author: xottabych007,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-14 12:20:05