如今有一个需求,就是经过连接调到指定页面的位置,否则就得不一样连接不一样页面,那样工做量大以外,还太浪费。因而决定在一个页面中,经过连接跳到指定位置。须要跟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
来进行处理
不足之处
参考连接