it-swarm.com.de

Wie kann ich window.location.hash aktualisieren, ohne das Dokument zu überspringen?

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!

Aktualisieren

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;

            }
    });
});
141
alex

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

220
Attila Fulop

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);
49
Derek Hunziker

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.

25
Gavin Brock

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

13
user706270

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.

10
aldemarcalazans

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.

1
Jon B

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');
0
Rohit Dhiman

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.

0
Mike Vallano

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.

0
Andrew