成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

vue-sticky組件詳解

phodal / 1553人閱讀

摘要:但當該元素的位置移出設(shè)置的視圖范圍時,其定位效果將變成,并根據(jù)設(shè)置的等作為其定位參數(shù)。另外,筆者在網(wǎng)上找過相關(guān)的組件。面向人群急于使用組件的同學(xué)。若頁面大小發(fā)現(xiàn)變化,原顯示的位置可能與頁面變化后的不一致。

sticky簡介

sticky的本意是粘的,粘性的,使用其進行的布局被稱為粘性布局。

sticky是position屬性新推出的值,屬于CSS3的新特性,常用與實現(xiàn)吸附效果。

設(shè)置了sticky布局的元素,在視圖窗口時,與靜態(tài)布局的表現(xiàn)一致。

但當該元素的位置移出設(shè)置的視圖范圍時,其定位效果將變成fixed,并根據(jù)設(shè)置的left、top等作為其定位參數(shù)。

具體效果如下,當頁面滾動至下方,原本靜態(tài)布局的「演職員表」將變?yōu)閒ixed布局,固定在頁面頂部。

sticky兼容性

下圖可見,除了IE以外,目前絕大部分瀏覽器都是支持sticky布局。

需求背景

但是實際情況并不如上圖展示的那么美好,在360安全瀏覽器上,并不支持sticky布局,即使使用極速模式(使用chrome內(nèi)核運行)也不支持。

另外,筆者在網(wǎng)上找過相關(guān)的vue-sticky組件。但是使用起來并不是那么順手,而且看其源碼也是一頭霧水,用著不踏實。

所以自己寫了一個,希望通過本文能將組件分享出去,也希望將本組件的原理講清楚。讓其他同學(xué)在使用的時候能更踏實一些。遇到坑也知道該怎么去填。希望能幫到大家。

面向人群

急于使用vue-sticky組件的同學(xué)。直接下載文件,拷貝代碼即可運行。

喜歡看源碼,希望了解組件背后原理的同學(xué)。
其實本sticky組件原理很簡單,看完本文,相信你一定能把背后原理看懂。
剛接觸前端的同學(xué)也可以通過本文章養(yǎng)成看源碼的習慣。打破對源碼的恐懼,相信自己,其實看源碼并沒有想象中的那么困難

組件完整源碼如下



技術(shù)難點

sticky效果需要解決這么幾個問題

占位問題,sticky實現(xiàn)原理,無非是在特定超出視圖時,將內(nèi)容的布局設(shè)為fixed。但將內(nèi)容設(shè)置為fixed布局時,內(nèi)容將脫離文檔流,原本占據(jù)的空間將被釋放掉,這將導(dǎo)致頁面空了一塊后其他內(nèi)容發(fā)生位移。

頁面resize后位置問題。當使用fixed定位時,其定位將根據(jù)頁面進行。若頁面大小發(fā)現(xiàn)變化,原顯示的位置可能與頁面變化后的不一致。這時需要重新設(shè)置。

橫向滾動條問題。本質(zhì)上和resize是同一個問題,需要監(jiān)聽scroll事件,當頁面發(fā)送無相關(guān)方向的位移時,需要重新計算其位置,例如前面的sticky效果示例中設(shè)置了「演職員表」的top值,當其fixed后,滾動X軸,需要重新設(shè)置fixed的left參數(shù)。讓元素始終位于頁面相同位置

實現(xiàn)思路

組件有兩層容器

一個是內(nèi)容slot的容器$content

一個是內(nèi)容容器$content的sticky盒子容器$box

即包圍關(guān)系為$sticky-box($content(slot))

監(jiān)聽vue的mounted事件

這時內(nèi)容slot已經(jīng)被渲染出來

獲取slot容器$content的寬高,設(shè)置到$box容器上

設(shè)置$box容器寬高是為了當后續(xù)$content容器Fixed后,$box容器仍在頁面中占據(jù)空間。

const style = window.getComputedStyle(this.$refs.$content)
this.boxStyle.width = style.width
this.boxStyle.height = style.height

監(jiān)聽scroll事件

在事件中獲取容器$content在頁面中的位置,并將其與預(yù)設(shè)值進行大小比較,判斷$content是否應(yīng)該fixed

怎么便捷地獲取$content在頁面中的位置呢?直接使用Element.getBoundingClientRect()函數(shù),該函數(shù)將返回{left,top}分別表示dom元素距離窗口的距離。詳細可參看MDN文檔

const { $content, $box } = this.$refs
const { contentStyle } = this
const boxTop = $box.getBoundingClientRect().top
const boxLeft = $box.getBoundingClientRect().left
const contentTop = $content.getBoundingClientRect().top
const contentLeft = $content.getBoundingClientRect().left

比較boxTop與預(yù)設(shè)值top的大小,當boxTop比預(yù)設(shè)值值要小時,即內(nèi)容即將移出規(guī)定的視圖范圍。這時將內(nèi)容容器$content設(shè)置為fixed。并設(shè)置其top值(即預(yù)設(shè)的top值,吸頂距離),left值與盒子位置相同,故設(shè)置為盒子距離的left值

當boxTop比預(yù)設(shè)值值要大時,即內(nèi)容重新返回的視圖范圍。則將內(nèi)容容器$content重新設(shè)置會靜態(tài)布局,讓其重新回到盒子布局內(nèi)部。由于靜態(tài)布局不受left和top的影響,所以不需要設(shè)置left和top

if (boxTop > parseInt(this.top) && this.isFixedY) {
  contentStyle.position = "static"
} else if (boxTop < parseInt(this.topI) && !this.isFixedY) {
  contentStyle.position = "fixed"
  contentStyle.top = this.top
  contentStyle.left = `${boxLeft}px`
}

在scroll事件中,除了Y軸方向上的滾動,還可能發(fā)生X軸方向的滾動。這些需要重新設(shè)置fixed元素的left值,讓其與盒子容器的left值一致

// 當位置距左位置不對時,重新設(shè)置fixed對象left的值,防止左右滾動位置不對問題
if (contentLeft !== boxLeft && this.left === "unset") {
  const { $box } = this.$refs
  const { contentStyle } = this
  const boxTop = $box.getBoundingClientRect().top
  const boxLeft = $box.getBoundingClientRect().left
  if (contentStyle.position === "fixed") {
    contentStyle.top = this.top
    contentStyle.left = `${boxLeft}px`
  }
}

最后,是監(jiān)聽頁面的resize事件,防止頁面大小變化時,fixed相對頁面的變化。同樣的,重新設(shè)置left值

// 當位置距左位置不對時,重新設(shè)置fixed對象left的值,防止左右滾動位置不對問題
const { $box } = this.$refs
const { contentStyle } = this
const boxTop = $box.getBoundingClientRect().top
const boxLeft = $box.getBoundingClientRect().left

if (contentStyle.position === "fixed") {
  contentStyle.top = this.top === "unset" ? `${boxTop}px` : this.top
  contentStyle.left = this.left === "unset" ? `${boxLeft}px` : this.left
}

需要注意的地方

目前僅支持top與left值的多帶帶使用,暫不支持同時設(shè)置

目前僅支持px單位,暫不支持rem及百分比單位

設(shè)置內(nèi)容樣式時需要注意,設(shè)置定位相關(guān)屬性需要設(shè)置在box容器上,例如設(shè)置"displCy: inline-block;","verticCl-Clign: top;","margin"

設(shè)置外觀樣式,如背景,邊框等,則設(shè)置在slot內(nèi)容中

即內(nèi)容content-box以外的設(shè)置在box容器中,content-box以內(nèi)的樣式,則設(shè)置在slot內(nèi)容中

盒子容器不需要設(shè)置position屬性,即使有也會被沖刷掉。因為程序?qū)?nèi)部重新設(shè)置position的值

同樣的,在樣式中設(shè)置盒子容器的left和top值也是無效的,會被程序內(nèi)部重新設(shè)置。只能通過dom屬性值傳遞到組件中進行設(shè)置

后續(xù)優(yōu)化

目前本組件僅實現(xiàn)了基本功能,后續(xù)還將繼續(xù)優(yōu)化以下功能

slot內(nèi)容中,如果有圖片,如果獲取設(shè)置寬高,(監(jiān)聽所有圖片的load事件,重新設(shè)置容器的高寬)

目前僅在mounted中獲取slot的寬高,這僅僅是dom元素被渲染,但是dom內(nèi)容是否加載完畢并不知道的,如img標簽,后續(xù)在slot中,監(jiān)聽所有img標簽的load事件,load中,重新設(shè)置組件容器的大小

slot內(nèi)容有變化時,設(shè)置容器

同樣的,當slot內(nèi)容變化后,重新設(shè)置$content的寬高

具體如何實現(xiàn),暫時還沒有頭緒

移動端適配

目前只測試了在PC中的效果,暫未在移動端做測試。不排除移動端使用存在坑

單位適配

目前只支持PX單位,未支持rem,百分百等單位

left和top值的混合使用,目前只支持單個屬性的使用,暫不支持同時設(shè)置

項目源碼及示例 第一稿寫完了,撒花花

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/98139.html

相關(guān)文章

  • Vue 組件通信詳解

    摘要:父子組件通信兄弟組件通信跨級組件通信父傳子子組件用接收,父組件用發(fā)送父組件紅樓夢西游記三國演義水滸傳子組件子傳父子組件用有的版本名稱只能小寫發(fā)送,父組件自定義事件然后在方法中接收父組件不能加括號子組件點擊把傳給父組件可以傳 父子組件通信: props、 $parent / $children、 provide / inject 、 ref 、 $attrs / $listeners ...

    mikasa 評論0 收藏0
  • react進階系列:高階組件詳解(三)

    摘要:在前端基礎(chǔ)進階八深入詳解函數(shù)的柯里化一文中,我有分享柯里化相關(guān)的知識。雖然說高階組件與柯里化都屬于比較難以理解的知識點,但是他們組合在一起使用時并沒有新增更多的難點。 可能看過我以前文章的同學(xué)應(yīng)該會猜得到當我用New的方法來舉例學(xué)習高階組件時,接下來要分享的就是柯里化了。高階組件與函數(shù)柯里化的運用是非常能夠提高代碼逼格的技巧,如果你有剩余的精力,完全可以花點時間學(xué)習一下。 在前端基礎(chǔ)進...

    zhangxiangliang 評論0 收藏0
  • react進階系列 - 高階組件詳解四:高階組件的嵌套使用

    摘要:前面有講到過很多頁面會在初始時驗證登錄狀態(tài)與用戶角色。這個時候就涉及到一個高階組件的嵌套使用。而每一個高階組件函數(shù)執(zhí)行之后中所返回的組件,剛好可以作為下一個高階組件的參數(shù)繼續(xù)執(zhí)行,而并不會影響基礎(chǔ)組件中所獲得的新能力。 前面有講到過很多頁面會在初始時驗證登錄狀態(tài)與用戶角色。我們可以使用高階組件來封裝這部分驗證邏輯。封裝好之后我們在使用的時候就可以如下: export default w...

    LMou 評論0 收藏0
  • Vuet.js規(guī)則詳解,它是你不知道的強大功能?

    摘要:事先將狀態(tài)更新的規(guī)則寫好,然后將規(guī)則注入到組件中,然后狀態(tài)按照預(yù)訂的規(guī)則來進行更新。主動型和被動型規(guī)則內(nèi)置了這幾種常見的規(guī)則,除了規(guī)則外,其他都是屬于主動型更新規(guī)則,在達到一定的條件上會自動觸發(fā)狀態(tài)更新。 Vuet.js是什么? Vuet.js是給Vue.js提供狀態(tài)管理的一個工具,與vuex不同,它是一種崇尚規(guī)則定制的狀態(tài)管理模式。事先將狀態(tài)更新的規(guī)則寫好,然后將規(guī)則注入到組件中,然...

    張率功 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<