国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

純 CSS 檢測滾動的速度和方向

開發 前端
說起原理,其實和JS是差不多的,都是有個類似于定時、延時的機制。那具體如何做呢?下面一步一步來介紹。

CSS可以做的事情越來越越多了。

我們經常會碰到這樣的場景,很多網頁會在右下角放一個固定入口,有可能是返回頂部,有可能廣告,為了避免干擾,在頁面滾動時,會把這些入口臨時收起來,停止滾動后再出現,就像這樣

圖片圖片

通常我們實現這樣的效果會借助JS的定時器,并且監聽頁面滾動,其實也不復雜,大概是這樣實現

let timer;
window.addEventListener('scroll', function(){
  // 是否在滾動
  isScroll = true
  timer && clearTimeout(timer)
  timer = setTimeout(() => {
    isScroll = false
  }, 150)
})

現如今,CSS也能實現這樣的功能了,也就是可以檢測頁面是否在滾動,進一步,還能檢測滾動的速度和方向,一起來看看吧~

一、CSS 檢測原理

說起原理,其實和JS是差不多的,都是有個類似于定時、延時的機制。那具體如何做呢?下面一步一步來介紹。

比如,我們有這樣一個可以滾動的頁面;

<body>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
	...
</body>

簡單修飾一下,效果是這樣的;

圖片圖片

然后我們需要用 CSS檢測滾動的進度,該如何做呢?沒錯,就是用 CSS變量。

假設有一個這樣的動畫,--scroll-position從0變到100,如下:

@keyframes adjust-pos {
  form {
     --scroll-position: 0;
  }
  to {
    --scroll-position: 100;
  }
}

為了方便演示,我們可以把這個動畫的變化過程顯示在頁面上;

<div class="debug" hidden>
  <div data-id="--scroll-position"></div>
</div>

這里利用CSS計數器,直接用偽元素顯示CSS變量值;

具體實現如下:

:root {
  animation: adjust-pos linear 3s;
}
.debug{
  counter-reset: scroll-position calc(var(--scroll-position) * 1);
}
[data-id="--scroll-position"]::after {
  content: "--scroll-position: " counter(scroll-position);
}

現在效果如下:

圖片圖片

現在數字直接從0變到了100,沒有中間的過程。

這是因為--scroll-position是一個自定義變量,無法直接過渡。為了使這個變量也能像普通的過渡屬性自動過渡,需要用到CSS @property,也就是需要注冊這個變量,讓瀏覽器認為這是一個合法的 CSS 變量。

@property --scroll-position {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

這段代碼表示--scroll-position是一個number類型的數據,是一個合法的,可以過渡的類型,自然也就有動畫了,效果如下:

圖片圖片

然后我們加上滾動驅動動畫,讓這個動畫跟隨頁面滾動。

:root {
  animation: adjust-pos 3s linear both;
  animation-timeline: scroll();
}

效果如下,這樣就能檢測到滾動的具體位置了。

圖片圖片

當然,僅僅這樣還是不夠的,我們只知道了滾動的進度,并不知道滾動的狀態。

為了知道滾動的速度,我們還需要另一個變量,假設是--scroll-position-delayed。

@property --scroll-position-delayed {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}
@keyframes adjust-pos {
  form {
     --scroll-position: 0;
    --scroll-position-delayed: 0;
  }
  to {
    --scroll-position: 100;
    --scroll-position-delayed: 100;
  }
}

這樣就有了兩個變量在同時變化,效果如下:

圖片圖片

同時變化沒有什么意義,我們需要加一點延時,就像 JS的定時器一樣,這里我們可以直接通過transition來實現。

body{
  margin: 0;
  transition: --scroll-position-delayed 0.15s linear;
}

這里的0.15s表示--scroll-position-delayed在變化時需要0.15s的時間,而--scroll-position是瞬時完成的,所以就相當于--scroll-position-delayed始終比--scroll-position慢了0.15秒,也就相當于延時了0.15s,實際效果如下:

圖片圖片

是不是可以很清楚的看到下面的數值要比上面的慢一點?

有了這個時間差,我們就可以判斷當前的滾動狀態了。

比如我們可以用一個變量--scroll-velocity來表示兩者的差值。

body{
  --scroll-velocity: calc(var(--scroll-position) - var(--scroll-position-delayed));
}

效果如下:

圖片圖片

通過這個差值,我們是不是就能發現一些規律?

  1. 當--scroll-velocity為0時,表示滾動停止,否則表示正在滾動中。
  2. 當--scroll-velocity大于0時,表示滾動方向為下。
  3. 當--scroll-velocity小于0時,表示滾動方向為上。
  4. 還可以從--scroll-velocity的絕對值上考慮,絕對值越大,表示滾動速度越快,反之則越慢。

這就是CSS檢測的原理了,是不是還算簡單呢?不過這還沒完,還需要具體實現,比如怎么根據這個變量來匹配對應的樣式。

二、CSS 樣式查詢

回到文章開頭,我們如何檢測是否正在滾動呢,并且在滾動的時候隱藏右下角懸浮按鈕呢?下面就來實現這樣一個功能。

既然當--scroll-velocity為0時,就表示滾動停止,那我們是不是可以直接用樣式查詢來匹配呢?

@container - CSS: Cascading Style Sheets | MDN (mozilla.org)[1]

CSS 樣式查詢是容器查詢的一部分,從名稱也可以看出,它可以查詢元素的樣式,進而設置額外的樣式。比如默認是隱藏的。

.back{
  transform: translateX(100%);
  transition: .2s;
}

當匹配到--scroll-velocity:0時,顯示這個懸浮按鈕,就可以這樣來實現。

@container style(--scroll-velocity: 0) {
  .back{
    transform: translateX(0);
  }
}

效果如下:

圖片圖片

好像并沒有起效果?其實和前面的動畫原理差不多,這是一個CSS自定義變量,無法直接檢測到變化的值。這里有一個解決方案,為了保證能夠樣式查詢到,需要用@property注冊一下:

@property --scroll-velocity {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

這樣就能完美檢測了。

你也可以訪問線上鏈接來查看實際效果。

  • CSS scroll-speed (juejin.cn)[2]

是不是非常簡單?

三、CSS 變量計算

除了使用樣式查詢外,我們還可以用CSS變量的計算方式來實現。

什么意思呢?比如我們想知道是否在滾動,其實就是兩個狀態,那能不能用0和1來表示是否在滾動呢?那就需要做一點點變換了。

現在--scroll-velocity表示差值,范圍可能是-50~50,那如何轉換成1~0呢,很簡單,直接除以自身就行了, 比如-50/-50和50/50結果都是1,有人會奇怪0/0會不會無限大,沒關系,這里CSS計算的結果還是0,實現如下:

body{
  --scroll-velocity: calc(var(--scroll-position) - var(--scroll-position-delayed));
  --scroll-dynamic: calc(var(--scroll-velocity) / var(--scroll-velocity));
}

這樣的話,我們就無需樣式查詢來改變右下角懸浮按鈕的狀態了,直接用--scroll-dynamic來控制transform

.back{
  transform: translateX(calc(var(--scroll-dynamic) * 100%));
}

看看效果:

圖片圖片

不一樣的實現也能得到相同的效果,你也可以訪問線上鏈接來查看實際效果。

  • CSS scroll-dynamic - (juejin.cn)[3]

除了可以得到是否在滾動,還能計算得到滾動方向,比如1表示向下,-1表示向上,我們可以這樣來計算。

body{
  --scroll-velocity: calc(var(--scroll-position) - var(--scroll-position-delayed));
  --scroll-speed: max(var(--scroll-velocity), -1 * var(--scroll-velocity));
	--scroll-direction: calc(var(--scroll-velocity) / var(--scroll-speed));
}

看似有點復雜,其實也不難理解。比如當前差值是-30,那么,我們可以通過乘以-1,然后取兩者較大值,這樣就能得到絕對值了。

圖片圖片

上面其實是個“偏方”,關于絕對值,其實已經有CSS abs()了,只是現在還沒有支持,相信以后就能用上了。

然后用原值除以這個絕對值,就能得到1或者-1了。

利用這個特性,我們可以在不同的方向改變箭頭的指向。

.back{
  transform: scaleY(var(--scroll-direction));
}

效果如下:

圖片圖片

你也可以訪問線上鏈接來查看實際效果:

  • CSS scroll-dynamic (juejin.cn)[4]

四、更多有趣的案例

除了上面幾個應用,我還找了幾個有趣的案例。

比如下面這種蟲洞效果,在水平或者垂直方向滾動時,會有明顯的透視效果https://codepen.io/bramus/pen/wvRqVBm

圖片圖片

再比如這種上下滾動,可以看到不同方向上內容的傾斜角度不一樣,而且滾動越快,傾斜越大:https://codepen.io/bramus/pen/OJrxBaL

圖片

還有一個比較簡單實用的運動模糊滾動,也就是在滾動時,頁面會有模糊的效果:https://codepen.io/bramus/pen/XWoREjv

五、最后總結一下

說了這么多,核心原理其實就這么幾行,如下:

@property --scroll-position {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}
@property --scroll-position-delayed {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}
@keyframes adjust-pos {
  to {
    --scroll-position: 100;
    --scroll-position-delayed: 100;
  }
}
:root {
  animation: adjust-pos 3s linear both;
  animation-timeline: scroll();
}
body{
  transition: --scroll-position-delayed 0.15s linear;
  --scroll-velocity: calc(var(--scroll-position) - var(--scroll-position-delayed));
  --scroll-speed: max(var(--scroll-velocity), -1 * var(--scroll-velocity));
  --scroll-direction: calc(var(--scroll-velocity) / var(--scroll-speed));
  --scroll-dynamic: calc(var(--scroll-velocity) / var(--scroll-velocity));
}

其實原理還是比較好理解的,下面總結一下:

  1. 首先用CSS自定義變量--scroll-position實現一個從0到100的動畫,注意需要用@property注冊。
  2. 然后用CSS滾動驅動動畫將其關聯,實現在滾動的時候變量自動變化。
  3. 接著再定義一個相同動畫的變量--scroll-position-delayed,并設置過渡時間,這樣就會比--scroll-position變化的慢一點。
  4. 將這兩個變量相減可以得到差值--scroll-velocity。
  5. 通過這個差值--scroll-velocity就能獲得各種狀態了。
  6. 當--scroll-velocity為0時,表示滾動停止,否則表示正在滾動中。
  7. 當--scroll-velocity大于0時,表示滾動方向為下。
  8. 當--scroll-velocity小于0時,表示滾動方向為上。
  9. 還可以從--scroll-velocity的絕對值上考慮,絕對值越大,表示滾動速度越快,反之則越慢。
  10. 可以通過樣式查詢來匹配各種條件,不過需要用@property注冊。
  11. 通過 CSS calc 和 max計算可以得到更多狀態,比如滾動方向。
  12. 然后就是實際的運用了。
責任編輯:武曉燕 來源: 前端偵探
相關推薦

2024-04-28 09:12:16

CSS文本是否溢出前端

2020-05-11 14:55:44

CSS鼠標前端

2013-11-20 13:04:41

css瀏覽器渲染

2017-04-27 14:05:59

CSS動畫前端

2021-01-19 12:16:10

CSS前端UI

2024-08-29 08:13:58

2021-10-19 22:23:47

CSSBeautiful按鈕

2021-01-25 06:37:06

Css前端CSS 特效

2023-05-08 09:08:33

CSS前端

2022-02-21 07:02:16

CSSbeautiful按鈕

2013-04-08 14:07:28

CSS

2022-08-10 16:08:38

鴻蒙CSS

2020-11-04 13:55:06

CSS密室逃脫前端

2022-09-12 08:31:41

CSS3偽類URI

2023-11-22 07:47:34

2021-11-12 05:44:25

XDR威脅檢測網絡攻擊

2024-07-31 20:38:18

2022-10-31 19:10:39

CSS元素focus

2024-01-22 09:28:23

CSS前端滾動驅動

2022-08-29 17:39:53

應用開發css動畫
點贊
收藏

51CTO技術棧公眾號

亚洲国产精久久久久久久| 黄色免费网站在线观看| 好看的日韩av电影| www.日韩av.com| 男女裸体影院高潮| 亚洲校园激情春色| 欧美日本一区二区| 欧美美女搞黄| 五月天丁香久久| 91精品国产91久久久久青草| 电影中文字幕一区二区| 亚洲国产日韩精品在线| 大片在线观看网站免费收看| 亚洲综合av一区二区三区| 欧美一区二区视频观看视频| 亚洲精品无人区| 国产亚洲精品自拍| 久久久久久99| 中文日韩欧美| 久久另类ts人妖一区二区| 国产一区亚洲| 国产精品久久久久久久久久直播 | 亚洲电影在线看| 免费黄色电影在线观看| 亚洲精品偷拍| 亚洲国产精品成人精品| 91三级在线| 亚洲国产精品久久久久秋霞蜜臀| 丁香高清在线观看完整电影视频| 国产精品1024| 国产日韩视频在线播放| 国产精品1区2区| 日韩av综合在线观看| 国产日韩欧美在线一区| 91九色视频在线| 99久久www免费| 成人黄色片视频网站| 在线观看污网站| 欧美日韩国产精品一区二区三区四区 | 欧美视频三区在线播放| 午夜老司机精品| 爱高潮www亚洲精品| 欧美日韩亚洲一区二区三区| 日本一级在线观看| 日韩一级视频免费观看在线| 日韩漫画puputoon| 91干在线观看| 欧美日本亚洲韩国国产| 中文字幕一区二区三区在线乱码 | 免费看国产一级片| 亚洲欧洲日本在线| 香蕉影院在线| 国产剧情av麻豆香蕉精品| 国产午夜伦鲁鲁| 亚洲乱码精品一二三四区日韩在线| 欧美午夜黄色| 亚洲第一在线视频| 国产欧美日韩电影| 国产在线视频不卡| 青青草视频一区| 国产高潮免费视频| 另类av一区二区| 成人免费在线网| 亚洲在线观看免费视频| 四虎影视国产在线视频| 欧美精品在线网站| av大片在线| 久久99精品视频一区97| 欧美一区二区三区久久精品茉莉花 | 国产野外作爱视频播放| 色综合久久中文综合久久牛| 亚洲美女炮图| 热久久免费国产视频| 久久看片网站| 青青草av网站| 国产高清亚洲一区| 国产超碰在线观看| 亚洲精品有码在线| 一区二区电影在线观看| av网站在线观看不卡| 5月丁香婷婷综合| 日韩精品社区| 欧美精品激情在线| 国产一区视频在线观看免费| 国产欧美久久久久| 在线观看区一区二| 福利欧美精品在线| 欧美日韩一区二区视频在线| 国产精品久久久久久久久免费相片| 成人午夜在线影视| 国产成人精品视频在线| 大陆成人av片| 天堂va在线| 国产精品免费视频久久久| 成人av一区二区三区| 午夜视频在线| 精品成人乱色一区二区| 国产a亚洲精品| 久久婷婷国产综合尤物精品| 欧美黄在线观看| 免费看黄色一级大片| 亚洲精品国产欧美| 国产精品v日韩精品v欧美精品网站 | 91精品一区二区三区在线观看| 久久夜色电影| 草草视频在线免费观看| 欧美一区二区三区在线视频| 综合久久亚洲| 最新中文字幕在线观看| 97国产精品视频| 国产主播性色av福利精品一区| 欧美在线视频二区| 日韩欧美亚洲一二三区| 亚洲宅男一区| 国产福利影院在线观看| 色七七影院综合| 国产精品亚洲午夜一区二区三区| 色网站在线看| 国产成人一区二区三区免费看| 亚洲一区二区三区四区五区中文| 日韩一区二区三区高清在线观看| 欧美交受高潮1| 成人午夜激情片| 午夜av不卡| 一区二区三区四区久久| 日韩欧美亚洲一区二区| 日韩视频二区| 国产91在线视频蝌蚪| 久久这里精品国产99丫e6| 欧美三区免费完整视频在线观看| 婷婷综合网站| 国产人成在线观看| 韩国成人av| 欧美日韩国产大片| 黑人一区二区| 五月天婷婷在线视频| 国产一区二区在线网站| 国产麻豆视频精品| 涩涩涩在线视频| 久久久久国色av免费观看性色| 成人h动漫精品| 日本成人一区二区| 国产第一页视频| 97在线观看免费高清| 亚洲精品中文在线观看| 欧美大人香蕉在线| 高清日韩av电影| 日韩av电影免费在线| 亚洲精品国产美女| 91免费视频网| 欧美电影在线观看完整版| 成人片在线免费看| 欧美三级资源在线| 日韩综合在线视频| 日韩三区在线| 亚洲最大激情中文字幕| 在线一区二区观看| 天使萌一区二区三区免费观看| 性欧美18xxxhd| 超碰av在线免费观看| 国产精品久久久久久网站| 欧美中文字幕一区| 国产一区二区三区综合| 成人免费直播在线| 黄色av免费在线看| 午夜精品电影在线观看| 综合欧美国产视频二区| 亚洲品质自拍视频网站| 我不卡影院28| 欧美aa视频| 成色在线视频| 日韩精品久久久| 欧美大片免费观看在线观看网站推荐| 亚洲成人av资源| 免费av网站大全久久| 盗摄牛牛av影视一区二区| 国产污视频在线| 国产精品12345| 91最新国产视频| 国产三级一区二区| 久久一区二区三区电影| 日本三级在线观看网站| 欧美 日韩 国产 高清| 国产精品福利小视频| 国产成人自拍网| 五月国产精品| 日韩成人伦理| 成人免费淫片在线费观看| 看高清中日韩色视频| 欧美人在线视频| 在线播放/欧美激情| 国产日韩欧美精品综合| 在线亚洲国产精品网站| 日韩成人18| 伊人手机在线| 99re99| 第九区2中文字幕| 91成人免费在线观看| 久久中国妇女中文字幕| 欧美一区二区三区免费大片|