it-swarm.com.de

Wie kann man den Ankersprung beim Laden einer Seite deaktivieren?

Ich denke, das ist möglicherweise nicht möglich, ich werde versuchen, es so gut ich kann zu erklären ... Ich habe eine Seite mit Registerkarten (jquery powered), die von folgenden Elementen gesteuert wird:

Ich verwende diesen Code, wie er von einem anderen Benutzer aus einer vorherigen Frage bereitgestellt wurde.

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

dieser Code funktioniert gut, wenn ich die "Tabs" -Seite direkt besuche.

ich muss jedoch auf einzelne Registerkarten von anderen Seiten verweisen. Um dies zu tun, erhält der Code den window.location.hash und zeigt dann die entsprechende Registerkarte an.

die Seite "springt" nicht wegen "return false" zum Anker.

dieses Ereignis wird jedoch nur bei einem Klickereignis ausgelöst. Wenn ich also meine "Registerkarten" von einer anderen Seite besuche, wird der "Sprung" -Effekt ausgelöst. Um dem entgegenzuwirken, scrolle ich automatisch zum oberen Rand der Seite, aber ich möchte lieber, dass dies nicht der Fall ist.

gibt es eine Möglichkeit, "return false" zu simulieren, wenn die Seite geladen wird, um zu verhindern, dass der Anker "springt".

hoffe das ist klar genug.

vielen Dank

91
Ross

Funktioniert Ihr Fix nicht? Ich bin mir nicht sicher, ob ich die Frage richtig verstanden habe - haben Sie eine Demo-Seite? Du könntest es versuchen:

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

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

Bearbeiten: getestet und funktioniert in Firefox, IE & Chrome unter Windows.
Bearbeiten 2: Verschieben Sie setTimeout() in if-Block, Requisiten @vsync.

132
dave1010

Siehe meine Antwort hier: Stackoverflow Answer

Der Trick besteht darin, den Hashtag ASAP einfach zu entfernen und seinen Wert für den eigenen Gebrauch zu speichern:

Es ist wichtig, dass Sie diesen Teil des Codes nicht in die Funktionen $ () oder $ (window) .load () einfügen, da dies zu spät wäre und der Browser bereits zum Tag verschoben wurde.

// 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 () {});
    }
});
32
Larzan

Ich habe die Lösung von dave1010 verwendet, aber es war etwas nervös, als ich sie in die $ (). Ready-Funktion steckte. Also habe ich das gemacht: (nicht in $ (). Fertig)

    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
lopsided

Es gibt andere Möglichkeiten, um zu verfolgen, auf welcher Registerkarte Sie sich befinden. Möglicherweise setzen Sie einen Cookie oder einen Wert in einem verborgenen Feld usw.

Ich würde sagen, wenn Sie nicht möchten, dass die Seite beim Laden springt, ist es besser, eine dieser anderen Optionen als den Hash zu verwenden, da der Hauptgrund für die Verwendung des Hash vor ihnen ist, dass Sie genau das zulassen, was Sie tun will blocken.

Ein weiterer Punkt: Die Seite springt nicht, wenn Ihre Hash-Links nicht mit den Namen der Tags im Dokument übereinstimmen. Wenn Sie also den Hash weiterhin verwenden möchten, könnten Sie den Inhalt so manipulieren, dass die Tags einen anderen Namen haben. Wenn Sie ein konsistentes Präfix verwenden, können Sie trotzdem Javascript verwenden, um zwischen diesen zu wechseln.

Hoffentlich hilft das.

11
Spudley
  1. Der Browser springt zu <element id="abc" />, wenn http://site.com/#abc hash in der Adresse vorhanden ist und das Element mit der ID = "abc" sichtbar ist. Daher sollten Sie das Element standardmäßig nur ausblenden: <element id="anchor" style="display: none" />. Wenn auf der Seite kein sichtbares Element mit id = hash angezeigt wird, springt der Browser nicht.

  2. Erstellen Sie ein Skript, das den Hash in der URL überprüft und das prrpopriate-Element (das standardmäßig ausgeblendet ist) findet und zeigt.

  3. Deaktivieren Sie das standardmäßige Verhalten "Hash-ähnlicher Link", indem Sie ein Onclick-Ereignis an einen Link binden und als Ergebnis des Onclick-Ereignisses return false; angeben.

Als ich Tabs implementiert habe, habe ich so etwas geschrieben:

    <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>
9
Sergei Smirnov

dirty CSS behebt das Scrollen jedes Mal, wenn der Anker verwendet wird (nicht nützlich, wenn Sie weiterhin Anker für Bildsprünge verwenden möchten, sehr nützlich für Deeplinking):

.elementsWithAnchorIds::before {
   content: "";
   display: block;
   height: 9999px;
   margin-top: -9999px; //higher thin page height
}
3
anotheryou

Keine der Antworten ist für mich nicht gut genug. Ich sehe, dass die Seite zum Ankern springt und dann für einige Lösungen ganz oben steht. Hoffe, dass meine Funktion jemandem helfen wird.

/**
 * 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
kdmitry

Die akzeptierte Antwort funktioniert zwar gut, aber ich habe festgestellt, dass manchmal, besonders auf Seiten mit großen Bildern, die die Bildlaufleiste verwendet, wild herumspringt

 window.scrollTo(0, 0);

Was für den Benutzer durchaus ablenkend sein kann.

Die Lösung, auf die ich mich am Ende entschieden habe, ist eigentlich ziemlich einfach, und das ist die Verwendung einer anderen ID auf dem Ziel als die in location.hash verwendete.

Z.B:

Hier ist der Link auf einer anderen Seite

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

Wenn also ein Element mit der ID tab2 auf der Registerkartenseite vorhanden ist, springt das Fenster beim Laden dorthin.

So können Sie der ID etwas hinzufügen, um dies zu verhindern:

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

Und dann können Sie "-noScroll" an location.hash im Javascript anhängen:

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

In meinem Fall habe ich wegen der Verwendung von Anker-Links für CSS-Popup Folgendes verwendet:

Speichern Sie einfach das pageYOffset-Element beim Klicken und setzen Sie dann den ScrollTop auf Folgendes:

$(document).on('click','yourtarget',function(){
        var st=window.pageYOffset;
        $('html, body').animate({
                'scrollTop' : st
            });
});
1
Metro Polisue

Ich glaube, ich habe einen Weg für UI-Registerkarten gefunden, ohne die Funktionalität zu erneuern. Bisher habe ich keine Probleme gefunden.

    $( ".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);

Alles innerhalb einer bereiten Veranstaltung. Es gibt "tab_" für den Hash vor, funktioniert aber sowohl, wenn Sie darauf klicken, als auch die Seite mit Hash laden.

1
JRomero

Ein anderer Ansatz

Versuchen Sie zu überprüfen, ob die Seite gescrollt wurde und setzen Sie erst dann die Position zurück:

var scrolled = false;

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

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

Heres a demo

0
hitautodestruct

Ich habe mit diesen Lösungen keinen beständigen Erfolg gehabt.

Anscheinend aufgrund der Tatsache, dass der Sprung vor Javascript => Referenz erfolgt ( http://forum.jquery.com/topic/preventing-anchor-jump )

Meine Lösung ist, alle Anker standardmäßig mit CSS an der Spitze zu positionieren.

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

Verwenden Sie dann jquery, um zum übergeordneten Element des Zielankers oder zu einem Geschwister zu blättern (möglicherweise ein leeres em-Tag).

<a class="scroll-target" name="section3"></a><em>&nbsp</em>

jquery-Beispiel zum Scrollen für die Eingabe der URL mit Hash
(Seite darf nicht bereits in Fenster/Tab geladen sein, dies beinhaltet Links von anderen/fremden Quellen)

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

Sie sollten auch die Standardeinstellung für Ankerklicks auf der Seite verhindern und dann zu ihren Zielen blättern

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

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

Das Gute an dieser Methode ist, dass die Anker-Tag-Ziele strukturell neben dem relevanten Inhalt bleiben, obwohl ihre CSS-Position an der Spitze steht.

Dies sollte bedeuten, dass Suchmaschinen-Crawler kein Problem haben.

Ich hoffe, das hilft
Grau 

0
grayskale.com

Dies funktioniert mit 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
Lasithds

Ich hatte mit den oben genannten setTimeout-Methoden in Firefox nicht viel Erfolg.

Anstelle von setTimeout habe ich eine Onload-Funktion verwendet:

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

Es ist leider immer noch sehr unangenehm.

0
bozdoz

Mein Problem wurde dadurch gelöst:

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

Versuchen Sie Folgendes, um zu verhindern, dass der Client beim Hash-Verfahren (innerhalb Ihres Event-Handlers) vertikal scrollen kann:

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

(Browser neu zeichnen)

0
andy