經過連接如何找到指定位置

經過連接如何找到指定位置

如今有一個需求,就是經過連接調到指定頁面的位置,否則就得不一樣連接不一樣頁面,那樣工做量大以外,還太浪費。因而決定在一個頁面中,經過連接跳到指定位置。須要跟github的效果同樣javascript

github

經過上面的github圖,能夠看出幾個基本需求css

  • 跳轉時攜帶id,自動跳轉到指定位置
  • 被選中的元素具備 focus 效果
  • 被選中的元素具體頂部有一段距離
  • 點擊 document 時,清除選中效果,同時路由上刪除id
  • 點擊瀏覽器回退按鈕,能夠出現新進入時的效果

開啓挖掘之旅

鑑於上面的需求,經過hash(錨點)是能夠簡單實現上面的要求,我的固然但願能用瀏覽器及css解決的,就儘可能解決,如果不行只能經過js來儘量模擬出想要的效果。html

在此,咱們須要惡補2個知識點java

地址欄改變,頁面不刷新不滾動 介紹

經過github的效果,咱們知道地址欄是改變了,可是視覺上確實沒有感到有任何同樣(除了focus效果消失)。node

經過historyreplaceState即可以實現上述效果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的代碼 githubgithub

鄙人的代碼沒有那麼全面,可是原理是同樣的web

至此頁面刷新不跳轉便算完成了chrome

利用hash進行定位

利用錨點進行定位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()
})

效果圖
hash

經過上面的方式,即可以完成基本需求,可是有幾點須要探討一下

  • 定位的盒子沒法設置距離頂部多高,徹底由錨點說的算了
  • 若是攜帶了?v=1相似參數,錨點便徹底失效了

針對上面遺留的問題,使用js進行改版

鑑於使用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
}

效果圖

  • 不攜帶參數
    no-has-params

  • 攜帶參數
    has-params

至此,基本完成想要的需求

效果頁面連接

總結

  • 項目地址link
  • 谷歌瀏覽器會記住默認位置 link,但使用了該方法
    javascript {highlight=2} if ('scrollRestoration' in history) { history.scrollRestoration = 'manual'; }
    會與原始錨點方案有衝突

  • 滾動到指定位置,能夠經過scrollIntoView來實現,只是依舊跟錨點存在一樣的問題,沒法設置距離頂部的位置
  • 對於獲取scrollTop=0值的想法,能夠經過getBoundingClientRect來進行處理

不足之處

  • 使用js方案,先後的滾動能夠看出來,而是用錨點模式較好,如果不考慮設置距離頂部的高度,我的更加偏向於二者進行處理(經過是否攜帶參數來進行判斷)

參考連接

相關文章
相關標籤/搜索