簡短的回答是我通常使用history.replaceState()
來實現這一點,但還有很多事情要做。 MDN描述了這種方法:
更新的歷史堆棧上最新的條目有 指定的數據,標題,並且,如果提供的URL。數據被視爲DOM不透明的 ;您可以指定任何可以序列化爲 的JavaScript對象。
在實踐中,這是如何解決的,我創建了一個狀態對象,其狀態是我的頁面部分。我經常將這與優秀的Waypoints plugin一起使用,觸發基於航點的狀態更改。這段代碼很容易理解,請閱讀我的評論,這些評論將引導您閱讀它。
// 1- Sets up state object that will store each page section 'state'
var stateObj = { state0: "group" };
// 2- Setups up waypoint to indicate a new section
var yourNameWaypoint = new Waypoint({
// 3- Target an ID for waypoints to watch, corresponds to a page section
element: document.getElementById('page-id-target'),
handler: function(direction) {
// 4- Create down direction handler
if (direction === 'down') {
// 5- Assign stateObj a page state that corresponds to your page section
stateObj = { state1: "page-section-1" };
history.replaceState(stateObj, "Section Title", "#new-page-section-slug-here");
}
// 6- Do the same thing in the other direction now, reseting the URL to what it was before the waypoint was hit
if (direction === 'up') {
stateObj = { state0: "original-state" };
history.replaceState(stateObj, "Original Page Section Title", "original-page-slug-here");
}
}
});
讓哈希對應滾動位置有點困難。我修改了一個相當不錯的腳本來使其工作(http://jsfiddle.net/ianclark001/rkocah23/),但我會在這裏發佈原文。
這個想法很簡單。基本上,您正在讀取您在init
之內的上述函數中創建的每個網址哈希值,然後使用history.pushState()
將這些網址哈希值在scrollToCurrent
部分匹配。我發現我喜歡在滾動動畫中加入一些延遲,以使行爲更加正常(設置在500毫秒以下,但可以調整)。
(function(document, history, location) {
var HISTORY_SUPPORT = !!(history && history.pushState);
var anchorScrolls = {
ANCHOR_REGEX: /^#[^ ]+$/,
OFFSET_HEIGHT_PX: 50,
/**
* Establish events, and fix initial scroll position if a hash is provided.
*/
init: function() {
this.scrollToCurrent();
$(window).on('hashchange', $.proxy(this, 'scrollToCurrent'));
$('body').on('click', 'a', $.proxy(this, 'delegateAnchors'));
},
/**
* Return the offset amount to deduct from the normal scroll position.
* Modify as appropriate to allow for dynamic calculations
*/
getFixedOffset: function() {
return this.OFFSET_HEIGHT_PX;
},
/**
* If the provided href is an anchor which resolves to an element on the
* page, scroll to it.
* @param {String} href
* @return {Boolean} - Was the href an anchor.
*/
scrollIfAnchor: function(href, pushToHistory) {
var match, anchorOffset;
if(!this.ANCHOR_REGEX.test(href)) {
return false;
}
match = document.getElementById(href.slice(1));
if(match) {
anchorOffset = $(match).offset().top - this.getFixedOffset();
$('html, body').delay(500).animate({ scrollTop: anchorOffset});
// Add the state to history as-per normal anchor links
if(HISTORY_SUPPORT && pushToHistory) {
history.pushState({}, document.title, location.pathname + href);
}
}
return !!match;
},
/**
* Attempt to scroll to the current location's hash.
*/
scrollToCurrent: function(e) {
if(this.scrollIfAnchor(window.location.hash) && e) {
e.preventDefault();
}
},
/**
* If the click event's target was an anchor, fix the scroll position.
*/
delegateAnchors: function(e) {
var elem = e.target;
if(this.scrollIfAnchor(elem.getAttribute('href'), true)) {
e.preventDefault();
}
}
};
$(document).ready($.proxy(anchorScrolls, 'init'));
})(window.document, window.history, window.location);
_Am我只是聽滾動事件,然後檢查是否一個元素在檢視_是 - ?如果使用唯一的ID,頁面將滾動到#ID的URL – mplungjan
它應該是'e.preventDefault()'。 –
@mplungjan它將是唯一的ID,但我需要的是在滾動內容時更改URL,而不是URL來滾動內容。 – cwal