javascript - Belgeyi atlamadan window.location.hash değerini nasıl güncelleyebilirim?


Web sitemde bir kayar panel kurulu.

Animasyonu bitirdiğinde, hash'i şöyle ayarladım

function() {
   window.location.hash = id;
}

(bu bir geri aramadır ve id daha önce atanmıştır).

Bu, kullanıcının paneli yer imlerine eklemesine izin vermek için ve ayrıca JavaScript olmayan sürümün çalışması için iyi çalışıyor.

Ancak, hash'i güncellediğimde tarayıcı konuma atlıyor. Sanırım bu beklenen bir davranış.

Benim sorum şu: Bunu nasıl önleyebilirim? Yani, penceredeki hash'i nasıl değiştirebilirim ama hash varsa tarayıcının elemana kaydırmasını önleyebilirim? Bir çeşit event.preventDefault() gibi bir şey?

jQuery 1.4 ve scrollTo eklentisini kullanıyorum.

Çok teşekkürler!

Güncelle

İşte paneli değiştiren kod.

$('#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;

            }
    });
});

Cevap #1

Eski tarayıcılarda geri dönüşle modern tarayıcılarda history API kullanarak bir çözüm yolu vardır:

if(history.pushState) {
    history.pushState(null, null, '#myhash');
}
else {
    location.hash = '#myhash';
}

Kredi Lea Verou'ya gider

Cevap #2

Sorun, window.location.hash değerini bir öğenin ID özniteliğine atamanızdır. Tarayıcının o öğeye atlaması beklenen bir davranıştır, "preventDefault()" kullanıp kullanmadığınıza bakılmaksızın.

Bunun bir yolunu aşmanın bir yolu, karma değerinin başına şu şekilde rasgele bir değer eklemektir:

window.location.hash = 'panel-' + id.replace('#', '');

O zaman yapmanız gereken tek şey sayfa yüklendiğinde ön ekli karmayı kontrol etmektir. Ek bir bonus olarak, şimdi karma değeri sizin kontrolünüzde olduğundan ona doğru yumuşak bir şekilde kaydırma yapabilirsiniz...

$(function(){
    var h = window.location.hash.replace('panel-', '');
    if (h) {
        $('#slider').scrollTo(h, 800);
    }
});

Bunun her zaman çalışmasını istiyorsanız (sadece ilk sayfa yüklemesinde değil), hash değerindeki değişiklikleri izlemek ve doğru elemana anında geçmek için bir fonksiyon kullanabilirsiniz:

var foundHash;
setInterval(function() {
    var h = window.location.hash.replace('panel-', '');
    if (h && h !== foundHash) {
        $('#slider').scrollTo(h, 800);
        foundHash = h;
    }
}, 100);

Cevap #3

Ucuz ve kötü bir çözüm.. Çirkin #! stilini kullanın.

Bunu ayarlamak için:

window.location.hash = '#!' + id;

Bunu okumak için:

id = window.location.hash.replace(/^#!/, '');

Sayfadaki herhangi bir bağlantı noktası veya kimlik ile eşleşmediği için atlamayacaktır.

Cevap #4

Neden geçerli kaydırma konumunu almıyorsun, onu bir değişkene koymuyorsun, sonra hash'i atayıp sayfa kaydırmasını eski yerine geri koymuyorsun:

var yScroll=document.body.scrollTop;
window.location.hash = id;
document.body.scrollTop=yScroll;

bu işe yaramalı

Cevap #5

Modern tarayıcılar için Attila Fulop (Lea Verou) çözümü ve eski tarayıcılar için Gavin Brock çözümünün bir kombinasyonunu şu şekilde kullandım:

if (history.pushState) {
    // IE10, Firefox, Chrome, etc.
    window.history.pushState(null, null, '#' + id);
} else {
    // IE9, IE8, etc
    window.location.hash = '#!' + id;
}

Gavin Brock'un belirttiği gibi, id'yi geri almak için dizgiyi (bu durumda '"!"' içerebilen veya içermeyen) şu şekilde ele almanız gerekecek:

id = window.location.hash.replace(/^#!?/, '');

Bundan önce, user706270 tarafından önerilenine benzer bir çözümü denedim, ancak bu Internet Explorer ile iyi çalışmadı: Javascript motoru çok hızlı olmadığı için, kaydırmanın artıp azaldığını fark edebilirsiniz, bu da kötü bir görsel etki yaratıyor.

İlgili makaleler