Ich habe auf meiner Website ein Schiebefenster eingerichtet.
Als die Animation beendet war, habe ich den Hash so gesetzt
function() {
window.location.hash = id;
}
(Dies ist ein Rückruf und die id
wurde früher zugewiesen).
Dies funktioniert gut, damit der Benutzer das Panel mit einem Lesezeichen versehen kann und auch die Nicht-JavaScript-Version funktioniert.
Wenn ich den Hash jedoch aktualisiere, springt der Browser zum Speicherort. Ich denke, das ist erwartetes Verhalten.
Meine Frage ist: Wie kann ich das verhindern? Das heißt Wie kann ich den Hash des Fensters ändern, aber nicht den Browser zum Element scrollen, wenn der Hash vorhanden ist? Eine Art von event.preventDefault()
Art von Dingen?
Ich verwende jQuery 1.4 und das scrollTo Plugin .
Danke vielmals!
Hier ist der Code, der das Panel ändert.
$('#something a').click(function(event) {
event.preventDefault();
var link = $(this);
var id = link[0].hash;
$('#slider').scrollTo(id, 800, {
onAfter: function() {
link.parents('li').siblings().removeClass('active');
link.parent().addClass('active');
window.location.hash = id;
}
});
});
Es gibt eine Problemumgehung, wenn Sie die Verlaufs-API in modernen Browsern mit Fallback auf alten verwenden:
if(history.pushState) {
history.pushState(null, null, '#myhash');
}
else {
location.hash = '#myhash';
}
Kredit geht an Lea Verou
Das Problem ist, dass Sie window.location.hash auf das ID-Attribut eines Elements setzen. Es ist das erwartete Verhalten für den Browser, zu diesem Element zu springen, unabhängig davon, ob Sie "defineDefault ()" verwenden oder nicht.
Eine Möglichkeit, dies zu umgehen, besteht darin, dem Hash einen beliebigen Wert wie folgt voranzustellen:
window.location.hash = 'panel-' + id.replace('#', '');
Dann müssen Sie beim Laden der Seite nur nach dem vorangestellten Hash suchen. Als zusätzlichen Bonus können Sie sogar reibungslos zu ihm scrollen, da Sie jetzt den Hashwert steuern ...
$(function(){
var h = window.location.hash.replace('panel-', '');
if (h) {
$('#slider').scrollTo(h, 800);
}
});
Wenn Sie dies jederzeit benötigen (und nicht nur beim ersten Laden der Seite), können Sie eine Funktion verwenden, um Änderungen am Hashwert zu überwachen und schnell zum richtigen Element zu springen:
var foundHash;
setInterval(function() {
var h = window.location.hash.replace('panel-', '');
if (h && h !== foundHash) {
$('#slider').scrollTo(h, 800);
foundHash = h;
}
}, 100);
Billig und böse Lösung .. Verwenden Sie die hässlichen #! Stil.
Um es einzustellen:
window.location.hash = '#!' + id;
Um es zu lesen:
id = window.location.hash.replace(/^#!/, '');
Da es nicht mit Anker und ID auf der Seite übereinstimmt, springt es nicht.
Warum erhalten Sie nicht die aktuelle Bildlaufposition, setzen Sie sie in eine Variable, weisen Sie den Hash zu und setzen Sie die Seitenanzeige zurück auf den ursprünglichen Wert
var yScroll=document.body.scrollTop;
window.location.hash = id;
document.body.scrollTop=yScroll;
das sollte funktionieren
Ich habe eine Kombination aus Attila Fulop (Lea Verou) -Lösung für moderne Browser und Gavin Brock-Lösung für alte Browser wie folgt verwendet:
if (history.pushState) {
// IE10, Firefox, Chrome, etc.
window.history.pushState(null, null, '#' + id);
} else {
// IE9, IE8, etc
window.location.hash = '#!' + id;
}
Wie von Gavin Brock festgestellt, müssen Sie die Zeichenfolge (die in diesem Fall das "!" Haben kann oder nicht, das "!") Wie folgt behandeln, um die ID zurück zu erfassen:
id = window.location.hash.replace(/^#!?/, '');
Zuvor habe ich eine ähnliche Lösung wie die vom Benutzer706270 vorgeschlagene Lösung ausprobiert, die jedoch mit dem Internet Explorer nicht funktioniert hat: Da die Javascript-Engine nicht sehr schnell ist, können Sie feststellen, dass der Bildlauf zunimmt und abnimmt.
Ich bin nicht sicher, ob Sie das ursprüngliche Element ändern können, aber wie wäre es, wenn Sie die ID attr auf etwas anderes wie data-id setzen? Dann lesen Sie einfach den Wert von data-id für Ihren Hashwert und er springt nicht.
Diese Lösung hat für mich funktioniert
// store the currently selected tab in the hash value
if(history.pushState) {
window.history.pushState(null, null, '#' + id);
}
else {
window.location.hash = id;
}
// on load of the page: switch to the currently selected tab
var hash = window.location.hash;
$('#myTab a[href="' + hash + '"]').tab('show');
Und mein vollständiger JS-Code ist
$('#myTab a').click(function(e) {
e.preventDefault();
$(this).tab('show');
});
// store the currently selected tab in the hash value
$("ul.nav-tabs > li > a").on("shown.bs.tab", function(e) {
var id = $(e.target).attr("href").substr(1);
if(history.pushState) {
window.history.pushState(null, null, '#' + id);
}
else {
window.location.hash = id;
}
// window.location.hash = '#!' + id;
});
// on load of the page: switch to the currently selected tab
var hash = window.location.hash;
// console.log(hash);
$('#myTab a[href="' + hash + '"]').tab('show');
Diese Lösung hat für mich funktioniert.
Das Problem bei der Einstellung von location.hash
ist, dass die Seite zu dieser ID springt, wenn sie auf der Seite gefunden wird.
Das Problem mit window.history.pushState
ist, dass für jede Registerkarte, auf die der Benutzer klickt, ein Eintrag zum Verlauf hinzugefügt wird. Wenn der Benutzer dann auf die Schaltfläche back
klickt, wird zur vorherigen Registerkarte gewechselt. (Dies ist möglicherweise nicht das, was Sie wollen. Es war nicht das, was ich wollte).
Für mich war replaceState
die bessere Option, da nur der aktuelle Verlauf ersetzt wird. Wenn der Benutzer auf die Schaltfläche back
klickt, wird zur vorherigen Seite gewechselt.
$('#tab-selector').tabs({
activate: function(e, ui) {
window.history.replaceState(null, null, ui.newPanel.selector);
}
});
Schauen Sie sich die History API-Dokumente im MDN an.
Bei der Verwendung des Laravel-Frameworks hatte ich einige Probleme mit der Funktion route-> back (), da mein Hash gelöscht wurde. Um meinen Hash zu behalten, habe ich eine einfache Funktion erstellt:
$(function() {
if (localStorage.getItem("hash") ){
location.hash = localStorage.getItem("hash");
}
});
und ich habe es in meiner anderen JS-Funktion so eingestellt:
localStorage.setItem("hash", myvalue);
Sie können Ihre lokalen Speicherwerte beliebig benennen. meine namens hash
.
Wenn der Hash auf PAGE1 eingestellt ist, navigieren Sie zu PAGE2. Der Hash wird auf PAGE1 neu erstellt, wenn Sie auf PAGE2 Zurück klicken.