hash实现锚点平滑滚动定位

一、科普时间

hash

hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从 # 号开始的部分)。
location.hash=anchorname。

锚点

锚点是网页制作中超级链接的一种,又叫命名锚记。命名锚记像一个迅速定位器一样,是一种页面内的超级链接

二、锚点简单的栗子



  
    
    伪锚点
    
  
  
    

锚点1

锚点2

锚点1
锚点2

解析
 访问该页面的地址:http://127.0.0.1/anchor.html(我是在本地服务器上测试的)
 点击a链接锚点1,则页面会直接跳到红色的div(锚点1),同时,浏览器地址改变为http://127.0.0.1/anchor.html#anchor1
 虽然可以直接定位到制定的位置,但是效果很差,没有平缓的过渡效果。

三、改进过渡效果

1)前期理论准备
 既然hash值是对应锚点的id值,那如果改为js动态获取hash值,然后再根据hash值获得dom对象。最后,用js进行平缓过渡。
 基于这个思路,就必须要求hash的取名有独特性,不能跟页面中的任何一个id一致,否则会触发浏览器默认的锚点定位行为。

2)确定特殊hash命名
 hash命名直接取特殊的前缀:w_,比如锚点1对应的hash值为w_anchor1



  
    
    伪锚点
    
  
  
    

锚点1

锚点2

间隔1

间隔2

间隔3

间隔4

间隔5

间隔6

间隔7

间隔8

锚点1

间隔1

间隔2

间隔3

间隔4

间隔5

间隔6

间隔7

间隔8

锚点2

间隔1

间隔2

间隔3

间隔4

间隔5

间隔6

间隔7

间隔8

3)编写读取特殊hasn值的方法以及缓动方法(本示例不考虑兼容性)

(function(window, undefined){
    // 监听页面加载完成后,检查是否需要定位锚点
  window.onload = function(){
    scrollToAnchor();
  };

  // 监听地址栏url的hash值改变时,检查是否需要定位锚点
  window.onhashchange = function(){
    scrollToAnchor();
  };

  // 滚动到自定义的伪锚点
  function scrollToAnchor(){
    var hash = getHash(), // 获取url的hash值
      anchor = getAnchor(hash), // 获取伪锚点的id
      anchorDom, // 伪锚点dom对象
      anchorScrollTop; // 伪锚点距离页面顶部的距离

    // 如果不存在伪锚点,则直接结束
    if(anchor.length < 1){
      return;
    }

    anchorDom = getDom(anchor);
    anchorScrollTop = anchorDom.offsetTop;

    animationToAnchor(document.body.scrollTop, anchorScrollTop);
  }

  /* 
    @function 滚动到指定位置方法
    @param startNum {int} -- 开始位置
    @param stopNum {int} -- 结束位置
  */
  function animationToAnchor(startNum, stopNum){
    var nowNum = startNum + 10; // 步进为10

      if(nowNum > stopNum){
        nowNum = stopNum;
      }

      // 缓动方法
      window.requestAnimationFrame(function(){
        document.body.scrollTop = nowNum; // 当前示例页面,滚动条在body,所以滚动body

        // 滚动到预定位置则结束
        if(nowNum == stopNum){
          return;
        }

        animationToAnchor(nowNum, stopNum); // 只要还符合缓动条件,则递归调用
      });
  }

  // 获取锚点id
  function getAnchor(str){
    return checkAnchor(str) ? str.split("w_")[1] : "";
  }

  // 判断是否为特殊的hash值,也即是否为伪锚点
  function checkAnchor(str){
    return str.indexOf("w_") == 0 ? true : false;
  }

  // 获取hash值
  function getHash(){
    return window.location.hash.substring(1);
  }

  // 获取dom对象
  function getDom(id){
    return document.getElementById(id);
  }
})(window);

在线演示:https://wall-wxk.github.io/blogDemo/anchor/anchor.html
最后,附上完整示例源码



  
    
    伪锚点
    
  
  
    

锚点1

锚点2

间隔1

间隔2

间隔3

间隔4

间隔5

间隔6

间隔7

间隔8

锚点1

间隔1

间隔2

间隔3

间隔4

间隔5

间隔6

间隔7

间隔8

锚点2

间隔1

间隔2

间隔3

间隔4

间隔5

间隔6

间隔7

间隔8

喜欢我文章的朋友,扫描以下二维码,关注我的个人技术博客,我的技术文章会第一时间在博客上更新

点击链接wall的个人博客

hash实现锚点平滑滚动定位_第1张图片
wall的个人博客

你可能感兴趣的:(hash实现锚点平滑滚动定位)