经过连接如何找到指定位置

经过连接如何找到指定位置

如今有一个需求,就是经过连接调到指定页面的位置,否则就得不一样连接不一样页面,那样工做量大以外,还太浪费。因而决定在一个页面中,经过连接跳到指定位置。须要跟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方案,先后的滚动能够看出来,而是用锚点模式较好,如果不考虑设置距离顶部的高度,我的更加偏向于二者进行处理(经过是否携带参数来进行判断)

参考连接

相关文章
相关标签/搜索