頁面快速定位到指定位置的幾個方法

需求

頁面上有一排按鈕,懸浮在窗口頂端,不隨頁面滑動而滑動,這一組按鈕分別對應的是頁面的各個部分,點擊按鈕,頁面定位到對應的位置。javascript

需求分析

拿到這個需求,很天然的想到,解決這個最簡單的方法是使用錨點(能靠HTML和css解決的,儘可能不使用jscss

解法

想到使用錨點事情就比較簡單了,借用a標籤的href定位,很快就寫了一個Demo,
完整代碼:https://codepen.io/yangyang11...
關鍵代碼:html

<div id="content">
  <div class="btn-container">
    <a class="btn" href="#anchor1">錨點1</a>
    <a class="btn" href="#anchor2">錨點2</a>
    <a class="btn" href="#anchor3">錨點3</a>
  </div>
  <div id="anchor1" class="anchor-con">anchor1</div>
  <div id="anchor2" class="anchor-con">anchor2</div>
  <div id="anchor3" class="anchor-con">anchor3</div>
</div>

這時候,點擊懸浮的button,頁面能夠實現快速定位。java

坑1

點了幾遍以後立馬就發現了一個坑,由於按鈕是懸浮的,而錨點定位,默認是定位到窗口頂端,這樣定位到的區域就會有一部分被懸浮的按鈕擋住
以下圖:
原始狀態:
圖片描述
點擊「錨點1」按鈕以後(黃色框起來的部分就是被遮蓋起來的部分):
圖片描述
由此引出一個問題,怎麼使a標籤的錨點不定位到窗口最頂端?json

怎麼使a標籤的錨點定位到窗口的任意位置

方法1:

網上搜了一些方法,其中有提到使用:target,主要添加幾行css瀏覽器

#anchor1:target, #anchor2:target, #anchor3:target {
  padding-top: 100px;  // 這裏更改padding-top的值使其定位到不一樣地方
}

效果以下圖:
圖片描述
雖然能夠實現文字的不被遮擋,可是實際上,對於固定大小的div來講,很容易影響div的內部佈局,故不適用我這裏的狀況(然而這裏的:target在其餘地方做用仍是很是大的。佈局

方法二

換別的思路,想了個巧辦法,在每一個須要定位的節點前面加一個輔助節點,輔助節點的高度能夠自定,錨點的實際定位的是這個輔助節點
完整代碼:https://codepen.io/yangyang11...
關鍵代碼:性能

<div class="btn-container">
    <a class="btn" href="#anchor1">錨點1</a>
    <a class="btn" href="#anchor2">錨點2</a>
    <a class="btn" href="#anchor3">錨點3</a>
  </div>
  <div class="anchor-con anchor1">
    <!--實際上定位的是這個輔助節點-->
    <div id="anchor1" class="assist-div"></div>
    anchor1
  </div>
  <div class="anchor-con anchor2">
    <div id="anchor2" class="assist-div"></div>
    anchor2
  </div>
  <div class="anchor-con anchor3">
    <div id="anchor3" class="assist-div"></div>
    anchor3
  </div>
輔助節點的css:
.assist-div {
  width: 1px;
  height: 1px;
  position: absolute;
  top: -100px; // 這裏能夠設任意高度 對應錨點最後離窗口頂端的距離
  left: 0;
}

這個方法的優勢:
(一)輔助節點能夠絕對定位 不影響佈局
(二)改變輔助節點的top值 能夠實現錨點定位到窗口任意位置
最後效果截圖:(點擊了「錨點2「按鈕)
圖片描述測試

坑2

正當我美滋滋的交付任務,坐等1h以後的聚餐的時候,PM來找我說,不行,移動端打開的時候,我切換點了幾下懸浮的按鈕以後,要點不少下返回鍵才能退出頁面。
我:對啊由於每點一次按鈕就在瀏覽器記錄裏面添加一條記錄
PM:這不行 須要解決掉
。。。
這是個問題,須要用戶點擊不少下才能退出頁面體驗確實很差,若是想要用戶點擊一次就退出頁面,就得始終保持history只有一條記錄,可是a標籤跳轉的話自動往history加一條記錄,我也不能對此作什麼。
。。。
這時候不得不使用js了,
我盯着錨點看了會兒(實際上看了半小時:) )發現:動畫

例如http://shili.com/Demo.html#content1 這樣的url,是能夠直接定位到http://shili.com/Demo.html 這個頁面的id爲content1的節點處的,這樣的話,我不使用a標籤,直接使用js去動態改變url後面的#id 的id,也能夠實現定位的效果,而且還能實現瀏覽器只保存一條記錄。

完整代碼:https://codepen.io/yangyang11...
關鍵代碼:

去除a標籤,改成使用div,並添加click:
<div class="btn-container">
    <div class="btn" onclick="goToAnchor('#anchor1')">錨點1</div>
    <div class="btn" onclick="goToAnchor('#anchor2')">錨點2</div>
    <div class="btn" onclick="goToAnchor('#anchor3')">錨點3</div>
</div>
  function goToAnchor(anchorId) {
    // 使用replace方法能夠保證前一次瀏覽不會在瀏覽器中保留記錄
    window.location.replace(window.location.href.split('#')[0] + anchorId);
  }

至此,需求就完成了。
可是就頁面定位到指定位置其實還有更好的辦法,就是使用js去獲取指定位置的offsetTop,這樣的話還能夠加滑動動畫,使定位的這個過程比較平滑。我沒有使用這個方法是由於,一我開始就一心想使用錨點結果只能遇坑填坑,二個人頁面中有不少摺疊的部分(相似於手風琴效果),因此每次的offsetTop均可能是不同的,點擊時都須要去獲取offsetTop的值再移動,比較麻煩並且耗性能。(emmm雖然我一開始就抗拒使用js去解決,最後仍是使用了,可是抉擇之下仍是使用性能消耗小的比較好
這裏也丟一下采用上面這個方法的關鍵代碼

document.getElementById('content').scrollTop = document.getElementById(anchorId).offsetTop - 100;

2019.3.26日更新
使用js去實現的話,還有一種方法,使用:Element.scrollIntoView方法,我試了下,這個方法也很好用,還能夠自定義滑動方式,性能上,相較於上面的js方法要好,代碼以下:

<!DOCTYPE html>
<html>
<head>
    <title>測試</title>
    <style type="text/css">
        html, body {
            width: 100%;
            height: 100%
        }
    </style>
</head>
<body>

<div style="width: 100%;height: 100%;background: red" onclick="scrollToView()"></div>
<div id="scroll" style="width: 100%;height: 100px;background: blue;"></div>
<div style="width: 100%;height: 100%;background: red"></div>

<script type="text/javascript">
    function scrollToView () {
        document.getElementById('scroll').scrollIntoView({
            block: 'start',
            inline: 'nearest',
            behavior: 'smooth'
        })
    }
</script>

</body>
</html>
相關文章
相關標籤/搜索