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
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.
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 () {});
}
});
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);
}
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.
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.
Erstellen Sie ein Skript, das den Hash in der URL überprüft und das prrpopriate-Element (das standardmäßig ausgeblendet ist) findet und zeigt.
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>
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
}
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
);
});
}
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>
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
});
});
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.
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 );
}
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> </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
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>
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.
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);
});`
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)