web-dev-qa-db-ja.com

ドキュメントをジャンプせずにwindow.location.hashを更新するにはどうすればよいですか?

私のウェブサイトにスライディングパネルが設定されています。

アニメーションが終了したら、ハッシュを次のように設定します

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

(これはコールバックであり、idは以前に割り当てられます)。

これはうまく機能し、ユーザーがパネルにブックマークを付けたり、非JavaScriptバージョンが機能したりできるようになります。

ただし、ハッシュを更新すると、ブラウザーはその場所にジャンプします。これは予想される動作だと思います。

私の質問は、どうすればこれを防ぐことができますか?つまりウィンドウのハッシュを変更するにはどうすればよいですか?ただし、notハッシュが存在する場合、ブラウザは要素までスクロールしますか?ある種のevent.preventDefault()ある種のもの?

JQuery 1.4と scrollToプラグイン を使用しています。

どうもありがとう!

更新

パネルを変更するコードは次のとおりです。

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

            }
    });
});
151
alex

古いブラウザーにフォールバックを備えた最新のブラウザーで履歴APIを使用することで回避策があります。

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

クレジットは Lea Vero

233
Attila Fulop

問題は、window.location.hashを要素のID属性に設定していることです。 「preventDefault()」であるかどうかに関係なく、ブラウザがその要素にジャンプするのは予想される動作です。

これを回避する1つの方法は、次のようにハッシュに任意の値をプレフィックスとして付けることです。

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

次に、ページの読み込み時にプレフィックス付きハッシュを確認するだけです。追加のボーナスとして、ハッシュ値を制御できるようになったため、スムーズにスクロールすることもできます...

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

これを常に(最初のページの読み込み時だけでなく)動作させる必要がある場合は、関数を使用してハッシュ値の変更を監視し、その場で正しい要素にジャンプできます。

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

安くて厄介なソリューション..#い#を使用してください!スタイル。

設定するには:

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

それを読むには:

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

ページ内で一致し、アンカーまたはIDがないため、ジャンプしません。

27
Gavin Brock

現在のスクロール位置を取得して、変数に入れてからハッシュを割り当て、ページスクロールを元の位置に戻すのはなぜですか。

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

これは動作するはずです

13
user706270

次のように、最新のブラウザーにはAttila Fulop(Lea Verou)ソリューションを、古いブラウザーにはGavin Brockソリューションを組み合わせて使用​​しました。

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

Gavin Brockが観察したように、IDを取得するには、次のように文字列(この場合は "!"を含む場合と含まない場合がある)を処理する必要があります。

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

その前に、私はuser706270によって提案されたものと同様の解決策を試みましたが、Internet Explorerではうまく機能しませんでした:そのJavascriptエンジンは非常に高速ではないため、スクロールが増減し、不快な視覚効果を生み出すことに気付くことができます。

10
aldemarcalazans

このソリューションは私のために働いた。

location.hashの設定に関する問題は、ページ上で見つかった場合、ページがそのIDにジャンプすることです。

window.history.pushStateの問題は、ユーザーがクリックする各タブの履歴にエントリを追加することです。次に、ユーザーがbackボタンをクリックすると、前のタブに移動します。 (これはあなたが望むものかもしれないし、そうでないかもしれない。それは私が欲しかったものではなかった)。

私にとって、replaceStateは現在の履歴のみを置き換えるという点でより良いオプションでした。したがって、ユーザーがbackボタンをクリックすると、前のページに移動します。

$('#tab-selector').tabs({
  activate: function(e, ui) {
    window.history.replaceState(null, null, ui.newPanel.selector);
  }
});

MDNの History API docs をご覧ください。

2
Mike Vallano

このソリューションは私のために働いた

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

そして、私の完全なjsコードは

$('#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');
1
Rohit Dhiman

元の要素を変更できるかどうかはわかりませんが、id attrの使用からdata-idなどの別のものへの切り替えはどうでしょうか。次に、ハッシュ値のdata-idの値を読み取るだけで、ジャンプしません。

1
Jon B

laravelフレームワークを使用する場合、ハッシュが消去されるため、route-> back()関数の使用にいくつかの問題がありました。ハッシュを保持するために、単純な関数を作成しました:

$(function() {   
    if (localStorage.getItem("hash")    ){
     location.hash = localStorage.getItem("hash");
    }
}); 

そして、私はこのように他のJS関数でそれを設定します:

localStorage.setItem("hash", myvalue);

ローカルストレージの値には任意の名前を付けることができます。 hashという名前の鉱山。

したがって、PAGE1でハッシュが設定されている場合、PAGE2に移動します。 PAGE2で[戻る]をクリックすると、PAGE1でハッシュが再作成されます。

0
Andrew