如今有一個需求,就是經過連接調到指定頁面的位置,否則就得不一樣連接不一樣頁面,那樣工做量大以外,還太浪費。因而決定在一個頁面中,經過連接跳到指定位置。須要跟github的效果同樣javascript
經過上面的github圖,能夠看出幾個基本需求css
id
,自動跳轉到指定位置focus
效果document
時,清除選中效果,同時路由上刪除id
鑑於上面的需求,經過hash
(錨點)是能夠簡單實現上面的要求,我的固然但願能用瀏覽器及css解決的,就儘可能解決,如果不行只能經過js來儘量模擬出想要的效果。html
在此,咱們須要惡補2個知識點java
經過github的效果,咱們知道地址欄是改變了,可是視覺上確實沒有感到有任何同樣(除了focus效果消失)。node
經過history
的replaceState
即可以實現上述效果git
// 記錄第一次的值 const firstTop = document.scrollingElement.scrollTop // 清空hash window.location.hash = "" // 地址欄刷新不跳轉 window.history.replaceState(null, null, window.location.pathname + window.location.search) // 再回滾以前的位置 document.scrollingElement.scrollTop = firstTop
github的代碼 github
鄙人的代碼沒有那麼全面,可是原理是同樣的web
至此頁面刷新不跳轉便算完成了chrome
利用錨點進行定位api
html
<a href="./base.html#two" class="header">two</a> > base.html <div class="wide segment" id="two"> <h2>two</h2> <div class="sc"> <div class="ui placeholder fluid active inverted"> <div class="image header"> <div class="line"></div> <div class="line"></div> <div class="line"></div> <div class="line"></div> </div> </div> </div> </div>
css
.wide { padding: 20px; border: 1px solid #333; } .wide .sc { padding: 20px; border: 1px solid transparent; } .wide:target .sc { border: 1px solid red; box-shadow: 0 0 0 .2em pink; }
js
// 連接改變頁面不刷新 const changeUrl = () => { const firstTop = document.scrollingElement.scrollTop window.location.hash = "" window.history.replaceState(null, null, window.location.pathname + window.location.search) document.scrollingElement.scrollTop = firstTop } /** * @description: 如果經過連接進入當前頁面,最好使用 `one` * 如此事件只執行一次便可 */ $(document).on('click', function () { changeUrl() })
效果圖
經過上面的方式,即可以完成基本需求,可是有幾點須要探討一下
?v=1
相似參數,錨點便徹底失效了鑑於使用js,那就須要徹底按上面的需求,進行js定製化,須要一個一個完成方可。
focus
效果code開啓
html
<a href="./update.html#one" class="header">one</a> // 攜帶參數 <a href="./update.html#two?v=1" class="header">two?v=1</a> > update.html <div class="wide " id="one"> <h2>one</h2> <div class="sc"> <div class="ui placeholder fluid"> <div class="image header"> <div class="line"></div> <div class="line"></div> <div class="line"></div> <div class="line"></div> </div> </div> </div> </div> <div class="wide " id="two"> <h2>two</h2> <div class="sc"> <div class="ui placeholder fluid"> <div class="image header"> <div class="line"></div> <div class="line"></div> <div class="line"></div> <div class="line"></div> </div> </div> </div> </div>
css
.wide .sc { padding: 20px; border: 1px solid transparent; } .wide.target .sc, .wide:target .sc { border: 1px solid red; box-shadow: 0 0 0 .2em pink; }
js
/** * @description: 經過url獲取對應元素 * @return: node */ const getEl = () => { const urlId = location.href.split('#')[1] if (!urlId) return null return document.getElementById(urlId.replace(/\?.*/, '')) } /** * @description: 初始進入頁面跳轉到指定位置,同時生成focus效果 */ const elScroll = () => { const el = getEl() if (!el) return $(el).addClass('target') // 此處用來獲取須要滾動的位置 const scrollY = el.getBoundingClientRect().top + document.scrollingElement.scrollTop - 40 $(document.scrollingElement).scrollTop(scrollY) } /** * @description: 監聽地址欄hash值變化 */ const listenHashChange = () => { window.addEventListener('hashchange', () => { elScroll() }, false) } /** * @description: 地址欄改變頁面不刷新 */ const changeUrl = () => { // 移除選中效果 getEl() && $(getEl()).removeClass('target') const firstTop = document.scrollingElement.scrollTop window.location.hash = "" window.history.replaceState(null, null, window.location.pathname + window.location.search) document.scrollingElement.scrollTop = firstTop }
效果圖
不攜帶參數
攜帶參數
至此,基本完成想要的需求
谷歌瀏覽器會記住默認位置 link,但使用了該方法
javascript {highlight=2} if ('scrollRestoration' in history) { history.scrollRestoration = 'manual'; }
會與原始錨點方案有衝突
對於獲取scrollTop=0
值的想法,能夠經過getBoundingClientRect
來進行處理
不足之處
參考連接