JavaScript實(shí)現(xiàn)內(nèi)容滾動(dòng)與導(dǎo)航標(biāo)簽互動(dòng)關(guān)聯(lián)方案
一、需求場(chǎng)景描述
1.先看演示效果
類似這種,當(dāng)也頁(yè)面左側(cè)內(nèi)容滾動(dòng)的時(shí)候,需要關(guān)聯(lián)激活左側(cè)導(dǎo)航節(jié)點(diǎn);當(dāng)點(diǎn)擊右側(cè)導(dǎo)航節(jié)點(diǎn)時(shí), 也會(huì)將左側(cè)對(duì)應(yīng)的內(nèi)容滾動(dòng)到可視區(qū)域頂部的場(chǎng)景,并不少見,比如知識(shí)類社區(qū),掘金查看文章時(shí),百度查看百科詞條時(shí),都有這種場(chǎng)景,而我的實(shí)際開發(fā)種也遇到此類需求。遂有此文。
2.需求分解
- 1.滾動(dòng)左側(cè)內(nèi)容,關(guān)聯(lián)激活右側(cè)導(dǎo)航節(jié)點(diǎn)
- 2.單擊右側(cè)導(dǎo)航節(jié)點(diǎn),右側(cè)相應(yīng)的段落滾動(dòng)到可視區(qū)頂部
二、關(guān)鍵技術(shù)點(diǎn)提前知
技術(shù)點(diǎn)1:Element.scrollIntoView()
1.scrollIntoView() 的作用:
scrollIntoView()方法會(huì)滾動(dòng)元素的父容器,使被調(diào)用scrollIntoView()的元素對(duì)用戶可見。
2.基本用法介紹:
var el = document.getElementById("p1"); // true 可以省略效果相同 el.scrollIntoView(true) // alignToTop:Boolean型參數(shù)。 // 如果為 true,元素的頂端將和其所在滾動(dòng)區(qū)的可視區(qū)域的頂端對(duì)齊。 // 如果為 false,元素的底端將和其所在滾動(dòng)區(qū)的可視區(qū)域的底端對(duì)齊。 el.scrollIntoView(false); // 可選,scrollIntoViewOptions:{behavior: "smooth", block: "end", inline: "nearest"} // 可選,behavior :定義動(dòng)畫過渡效果,"auto"或 "smooth" 之一。默認(rèn)為 "auto"。 // 可選,block:定義垂直方向的對(duì)齊,"start", "center", "end", 或 "nearest"之一。默認(rèn)為 "start"。 // 可選,inline:定義水平方向的對(duì)齊,"start", "center", "end", 或 "nearest"之一。默認(rèn)為 "nearest"。 el.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"}); el.scrollIntoView({block: "end"});
3.注意事項(xiàng)
普通的布局沒問題,但是要注意,取決于其它元素的布局情況,此元素可能不會(huì)完全滾動(dòng)到頂端或底端。比如整體上已經(jīng)到頂部了,無法再滾動(dòng),那么該元素就不會(huì)移動(dòng)到可視區(qū)的頂部。
技術(shù)點(diǎn)2:Element.getBoundingClientRect()
Element.getBoundingClientRect() 方法返回元素的大小及其相對(duì)于視口的位置。返回值是一個(gè) DOMRect 對(duì)象,這個(gè)對(duì)象是由該元素的 getClientRects() 方法返回的一組矩形的集合,就是該元素的 CSS 邊框大小。返回的結(jié)果是包含完整元素的最小矩形,并且擁有l(wèi)eft, top, right, bottom, x, y, width, 和 height這幾個(gè)以像素為單位的只讀屬性用于描述整個(gè)邊框。除了width 和 height 以外的屬性是相對(duì)于視圖窗口的左上角來計(jì)算的。
下面是它的打印信息示例:
console.dir(document.getElementById("p1").getBoundingClientRect())
如果是標(biāo)準(zhǔn)盒子模型,元素的尺寸等于width/height + padding + border-width的總和。如果box-sizing: border-box,元素的的尺寸等于 width/height。
三、實(shí)現(xiàn)思路分析
1.數(shù)據(jù)初始化處理
// 從內(nèi)容數(shù)據(jù)list中,獲取段落標(biāo)題作為導(dǎo)航標(biāo)題。并為導(dǎo)航節(jié)點(diǎn)增加href,以段落的id值作為href的值 this.list.map((item, i) => { this.activities.push({title: item.title, act: false, href: "#p" + i}); });
2.監(jiān)聽滾動(dòng)條,以便滾動(dòng)內(nèi)容時(shí),關(guān)聯(lián)激活右側(cè)導(dǎo)航標(biāo)簽
// 監(jiān)聽滾動(dòng)條 window.addEventListener("scroll", function (e) { // 防抖動(dòng)處理 clearTimeout(that.timeout) this.timeout = setTimeout(() => { that.activeNavNode(e) }, 100) });
3.實(shí)現(xiàn)點(diǎn)擊右側(cè)導(dǎo)航節(jié)點(diǎn),關(guān)聯(lián)左側(cè)內(nèi)容滾動(dòng)到可視區(qū)頂部
// dom中定位導(dǎo)航 navToPosition(item, index) { // 激活相應(yīng)的導(dǎo)航節(jié)點(diǎn),變色 this.active = index; // 根據(jù)導(dǎo)航節(jié)點(diǎn)的href信息即id信息,獲取對(duì)應(yīng)的元素節(jié)點(diǎn),通過 scrollIntoView 滾動(dòng)該元素到可視區(qū)頂部 document.querySelector(item.href).scrollIntoView(true); },
4.實(shí)現(xiàn)滾動(dòng)右側(cè)內(nèi)容,關(guān)聯(lián)激活左側(cè)導(dǎo)航節(jié)點(diǎn)
// 激活左側(cè)對(duì)應(yīng)的導(dǎo)航條 activeNavNode(e) { const nodes = document.getElementsByTagName("section") for (let i = 0; i < nodes.length; i++) { let node = nodes[i]; // 獲取該元素此時(shí)相對(duì)于視口的頂部的距離,即是元素頂部距離視口屏幕上邊的距離 let nodeY = node.getBoundingClientRect().y // 當(dāng)元素距離視口頂部的距離在 [0,200] 之間,設(shè)置激活該元素對(duì)應(yīng)左側(cè)的導(dǎo)航標(biāo)題,這個(gè)數(shù)字可以按需定義 // 這里關(guān)聯(lián)內(nèi)容和導(dǎo)航標(biāo)簽,是巧妙利用了內(nèi)容在元素集合中的索引序號(hào)和導(dǎo)航標(biāo)簽中的一致 // 即是 list 和 activities 和 nodes 中下標(biāo)相等的元素,具有對(duì)應(yīng)關(guān)聯(lián)的關(guān)系 if (nodeY <= 200 && nodeY >= 0) { this.active = Number(i) return } } },
四、完整 demo 示例代碼
到此這篇關(guān)于JavaScript實(shí)現(xiàn)內(nèi)容滾動(dòng)與導(dǎo)航標(biāo)簽互動(dòng)關(guān)聯(lián)方案的文章就介紹到這了,更多相關(guān)JS內(nèi)容滾動(dòng) 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript事件冒泡機(jī)制原理實(shí)例解析
這篇文章主要介紹了JavaScript事件冒泡機(jī)制原理實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01JavaScript 產(chǎn)生不重復(fù)的隨機(jī)數(shù)三種實(shí)現(xiàn)思路
在 JavaScript 中,一般產(chǎn)生的隨機(jī)數(shù)會(huì)重復(fù),但是有時(shí)我們需要不重復(fù)的隨機(jī)數(shù),如何實(shí)現(xiàn)?本文給于解決方法,需要的朋友可以參考下2012-12-12JS實(shí)現(xiàn)手機(jī)號(hào)脫敏、郵箱脫敏、身份證號(hào)脫敏、姓名脫敏等常見脫敏代碼示例
這篇文章主要給大家介紹了關(guān)于JS實(shí)現(xiàn)手機(jī)號(hào)脫敏、郵箱脫敏、身份證號(hào)脫敏、姓名脫敏等常見脫敏的相關(guān)資料,脫敏的目的是保護(hù)用戶隱私,一種常見的方式是顯示部分字符,用星號(hào)或其他字符替代,需要的朋友可以參考下2024-02-02微信小程序?qū)崿F(xiàn)彈出層禁止頁(yè)面滾動(dòng)
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)彈出層禁止頁(yè)面滾動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07