外話:實在是鬧不明白頭條是怎么對文章進行推薦的,頭大...
好了,進入今天的主題,利用定時器設計出網站經常會使用到的效果——圖片無縫滾動展示。
圖片無縫滾動效果
1、設計圖片滾動前的樣式
//這是頁面的內容,用到的圖片大家可以去我的網盤下載
<p>圖片無縫滾動</p>
<div id="img_move">
<ul>
<li><img src="./images/dhb.jpg" alt=""></li>
<li><img src="./images/hnrb.jpg" alt=""></li>
<li><img src="./images/rmrb.jpg" alt=""></li>
<li><img src="./images/jzrb.jpg" alt=""></li>
<li><img src="./images/nmrb.jpg" alt=""></li>
</ul>
</div>
//CSS設計樣式,只是最簡單的展示,大家也可以添加自己喜歡的
<style>
*{margin:0; padding: 0;}
p{
margin:0 auto;
text-align: center;
font-size:30px;
}
#img_move{
width:400px;
height:28px;
background-color: red;
margin:30px auto;
position: relative; //相對定位
overflow: hidden; //表示溢出這個元素大小的內容全部隱藏
}
#img_move ul{
position: absolute; //相對于img_move這個元素進行絕對定位
left:0;
top:0;//距離左為0,上為0,我理解的意思是ul的左上角與img_move這個元素的左上角重合了。
}
#img_move ul li{
width: 80px;
height:28px;
list-style: none;
float:left;
}
</style>
2、讓圖片動起來。這里需要用到offsetLeft(左右滾動用的),當然還有對應的offsetTop(上下滾動用的)。
(1)首先獲取到頁面上的各個元素
var oDiv = document.getElementById("img_move");
var oUl = oDiv.getElementsByTagName("ul")[0];
var aLi = oUl.getElementsByTagName("li");
(2)選擇對oUl這個元素進行滾動(主要是考慮到li過多,如果選擇li滾動會讓問題復雜起來)
function img_move(){
oUl.style.left = oUl.offsetLeft - 2 + "px"; //表示讓oUl元素向左移動2個像素
(3)讓oUl每隔30毫秒向左移動一次。你問我為什么選擇30毫秒,等做完整個例子后你可以修改一下這個毫秒數,看看有什么效果吧^_^
setInterval(img_move, 30);
做完上邊的步驟你會發現oUl這個元素動起來了,但是問題又出現了,你會發現oUl在移動過后漏出了img_move的背景色紅色,我們先來分析一下為什么會出現這種情況,看下圖
圖1 目前的布局
這個圖片表示當時了當時的運動場景,當oUl向左移動時,因為它就這么長,往左走后邊沒有東西了自然就意味著要漏出div的紅色。怎么辦?首先想到的肯定是在它后邊繼續加一組圖片,想法是絕對正確的,但下一組也走完了怎么辦?繼續加?O(∩_∩)O哈哈~估計你的網站空間很快就被圖片給用完了。我們只加一組圖片,怎么加?其實就是加了一個oUl自身內部的所有內容。
oUl.innerHTML += oUl.innerHTML
oUl.style.width = aLi[0].offsetWidth * aLi.length + "px"; //修改oUl的寬度
這樣就得到了下面這張圖
圖2 加了一組圖片的布局
接下來怎么辦呢?大家都知道,我們肉眼看東西也是有一定的時間延誤的,小于這個時間延誤大家是看不出來變化的,思路來了。看下圖
圖3 ul左移動到超過一半時
當oUl向左移動超過一半的時候,我們立馬把oUl的left設定為0,這樣oUl就又跳回到圖2的狀態繼續左移動。
function img_move()
{
if(oUl.offsetLeft < -oUl.offsetWidth/2)
{
oUl.style.left = 0;
}
//右移動時候的判斷條件
if(oUl.offsetLeft > 0)
{
oUl.style.left = -oUl.offsetWidth/2 + "px";
}
oUl.style.left = oUl.offsetLeft - 2 + "px"; //表示讓oUl元素向左移動2個像素,向右移動變成+2
}
再看看效果吧。
4、添加鼠標移入、移出效果
oDiv.onmouseover = function()
{
clearInterval(timer);
}
oDiv.onmouseout = function()
{
timer = setInterval(img_move, 30);
}
到此為止,圖片無縫滾動的展示效果就做出來了,是不是很簡單,O(∩_∩)O哈哈~再復雜的問題,你把它拆開來看,其實都很簡單。
文已經過原作者Ahmad 授權翻譯。
你是否經常希望有一個CSS特性可以輕松創建一個可滾動的容器? CSS scroll snap 可以做到這一點。在早期的前端開發中,我依靠 JS 插件來創建滑塊組件。有時,我們需要一種簡單的方法來快速將元素制作成可滾動的容器。現在,多虧了 CSSS scroll snap ,我們可以簡單做到這一點。
隨著移動設備和平板設備的興起,我們需要設計和構建可以輕觸的組件。以圖庫組件為例。用戶可以輕松地向左或向右滑動以查看更多圖像,而不是分層結構。
根據CSS規范,為開發者提供良好控制的滾動體驗是引入 CSS scroll snap的主要原因之一。它增強了用戶體驗,并使其更容易實現滾動體驗。
要創建一個滾動容器,以下是我們需要做的基本內容
舉個例子:
<div class="section">
<div class="section__item">Item 1</div>
<div class="section__item">Item 2</div>
<div class="section__item">Item 3</div>
<div class="section__item">Item 4</div>
<div class="section__item">Item 5</div>
</div>
.section {
white-space: nowrap;
overflow-x: auto;
}
多年來,使用white-space: nowrap是一種流行的CSS解決方案,用于強制元素保持內聯。不過,現在我們基本都使用 Flexbox :
.section {
display: flex;
overflow-x: auto;
}
這是創建滾動容器的基本方法。然而,這還不夠,這不是一個可用的滾動容器。
問題是,與滑動相比,它們并不能提供良好的體驗。在觸摸屏上滑動手勢的主要好處是,我們可以用一根手指水平或垂直滾動。
實際上需要將每個項目移動到它自己的位置。這并不是滑動,這是一種非常糟糕的體驗,通過使用CSS scroll snap,我們可以通過簡單地定義snap points來解決這個問題,它將使用戶更容易地水平或垂直滾動。
接著,我們來看看如何使用CSS scroll snap。
要在容器上使用scroll snap,它的子項目應該內聯顯示,這可以用我上面解釋的方法之一來實現。我選擇CSS flexbox:
<div class="section">
<div class="section__item">Item 1</div>
<div class="section__item">Item 2</div>
<div class="section__item">Item 3</div>
<div class="section__item">Item 4</div>
<div class="section__item">Item 5</div>
</div>
.section {
display: flex;
overflow-x: auto;
}
了這個,我們需要添加另外兩個屬性來讓scroll snap工作。我們應該在哪里添加它們?
首先,我們需要將scroll-snap-type添加到滾動容器中。在我們的示例中,是.section元素。然后,我們需要向子項(即.section__item)添加scrolln-snap-align。
.section {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
}
.section__item {
scroll-snap-align: start;
}
這里你可能想知道x mandatory和start是干嘛用的。不用擔心,這是本文的核心,下面會對其進行深入的講解。
這一刻,我對CSS scroll snap非常興奮,它使滾動更加自然。現在,讓我們深入研究scroll snap 屬性。
根據CSS規范,**scroll-snap-type ** 屬性定義在滾動容器中的一個臨時點(snap point)如何被嚴格的執行。
滾動容器的軸表示滾動方向,它可以是水平或垂直的,x值表示水平滾動,而y表示垂直滾動。
/* 水平*/
.section {
display: flex;
overflow-x: auto;
scroll-snap-type: x;
}
/* 垂直*/
.section {
height: 250px;
overflow-y: auto;
scroll-snap-type: y;
}
我們不僅可以定義Scroll Snap的方向,還可以定義它的嚴格程度。這可以通過使用scroll-snap-type值的andatory | proximity來實現。
mandatory:如果它當前沒有被滾動,這個滾動容器的可視視圖將靜止在臨時點上。意思是當滾動動作結束,如果可能,它會臨時在那個點上。如果內容被添加、移動、刪除或者重置大小,滾動偏移將被調整為保持靜止在臨時點上。
mandatory關鍵字意味著瀏覽器必須捕捉到每個滾動點。假設roll-snap-align屬性有一個start值。這意味著,滾動必須對齊到滾動容器的開始處。
在下圖中,每次用戶向右滾動時,瀏覽器都會將項目捕捉到容器的開頭。
.section {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
}
.section__item {
scroll-snap-align: start;
}
試著在下面的演示中向右滾動。如果你使用的是手機或平板電腦,可以向右移動滾動條或使用觸摸。應該能感受到每個項目是如何從其容器的開始抓取的。
演示地址:https://codepen.io/shadeed/pen/RwGaXKB
但是,如果該值是proximity,則瀏覽器將完成這項工作,它可能會吸附到定義的點(在我們的例子中start)。注意,proximity 是默認值,但是為了清晰起見,我們這里還是聲明一下它。
.section {
display: flex;
overflow-x: auto;
/* proximity is the default value, I added it for clarity reasons */
scroll-snap-type: x proximity;
}
滾動容器的子項目需要一個對齊點,它們可以對齊到這個點。我們可以用start, center或end。
為了更容易理解,下面是它的工作原理。
假設我們在滾動容器上有一塊磁鐵,這將有助于我們控制捕捉點。如果scroll-snap-type是垂直的,則對齊對齊將是垂直的。參見下圖:
子項目將吸附到其水平滾動容器的開始處。
子項目將吸附到其滾動容器的中心。
子項將對齊到其滾動容器的末尾。
有時,我們可能需要一種方法來防止用戶在滾動時意外跳過一些重要的項。如果用戶滾動太快,就有可能跳過某些項。
.section__item {
scroll-snap-align: start;
scroll-snap-stop: normal;
}
法動太快可能會跳過三個或四個項目,如下所示:
scroll-snap-stop的默認值是normal,要強制滾動捕捉到每個可能的點,應使用always。
.section__item {
scroll-snap-align: start;
scroll-snap-stop: always;
}
這樣,用戶可以一次滾動到一個捕捉點,這種方式有助于避免跳過重要內容。想象每個停止點都有一個停止標志,參見下面的動畫:
演示地址:https://codepen.io/shadeed/pen/JjRbXza
scroll-padding設置所有側面的滾動邊距,類似于padding屬性的工作方式。在下圖中,滾動容器的左側有50px的內邊距。結果,子元素將從左側邊緣捕捉到50px
直滾動也是如此。參見下面的示例:
.section {
overflow-y: auto;
scroll-snap-type: y mandatory;
scroll-padding: 50px 0 0 0;
}
scroll-margin設置滾動容器的子項之間的間距。在向元素添加邊距時,滾動將根據邊距對齊。參見下圖:
.item-2具有scroll-margin-left: 20px。結果,滾動容器將在該項目之前對齊到20px。請注意,當用戶再次向右滾動時,.item-3會捕捉到滾動容器的開頭,這意味著僅具有邊距的元素將受到影響。
scroll snap 的一個很好的用例是圖像列表,使用 scroll snap 提供更好的滾動體驗。
.images-list {
display: flex;
overflow-x: auto;
scroll-snap-type: x;
gap: 1rem;
-webkit-overflow-scrolling: touch; /* Important for iOS devices */
}
.images-list img {
scroll-snap-align: start;
}
注意,我使用x作為scroll-snap-type的值。
事例地址:https://codepen.io/shadeed/pen/jOMrxYO
滾動捕捉的另一個很好的用例是朋友列表。下面的示例摘自Facebook(一個真實的示例)。
.list {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
gap: 1rem;
scroll-padding: 48px;
padding-bottom: 32px;
-webkit-overflow-scrolling: touch;
}
.list-item {
scroll-snap-align: start;
}
請注意,滾動容器的padding-bottom:32px。這樣做的目的是提供額外的空間,以便box-shadow可以按預期顯示。
對于此用例,我感興趣的是將center作為scroll-snap-align的值。
.list {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
-webkit-overflow-scrolling: touch;
}
.list-item {
scroll-snap-align: center;
}
這在一個角色列表中是很有用的,角色在滾動容器的中間是很重要的
演示地址:https://codepen.io/shadeed/pen/KKgMJWa
使用scroll snap也可以用于垂直滾動,全屏展示就是一個很好的例子。
<main>
<section class="section section-1"></section>
<section class="section section-2"></section>
<section class="section section-3"></section>
<section class="section section-4"></section>
<section class="section section-5"></section>
</main>
main {
height: 100vh;
overflow-y: auto;
scroll-snap-type: y mandatory;
-webkit-overflow-scrolling: touch;
}
.section {
height: 100vh;
scroll-snap-align: start;
}
值得一提的是,對于scroll-snap-type,可以使用inline和block邏輯值。參見下面的示例
main {
scroll-snap-type: inline mandatory;
}
使用 CSS scroll snap時,請確保可訪問性。這是滾動對齊的一種不好用法,它阻止用戶自由滾動內容以讀取內容。
.wrapper {
scroll-snap-type: y mandatory;
}
h2 {
scroll-snap-align: start;
}
請務必不要這樣做。
這是我剛剛學到的一個新的CSS特性的長篇文章。我希望它對你有用。
我是小智,我們下期在見!
作者:Ahmad 譯者:前端小智 來源:ishadee
原文:https://ishade.com/article/css-scroll-snap/
T之家12月9日消息 微軟對Chromium開源項目非常感興趣,因為該項目對Edge和Chrome都有利。微軟最新的功能請求之一就是希望通過部署Edge HTML風格的滾動特性從而讓Chromium的滾動變得更加靈敏。
微軟打算將Impulse樣式(即EdgeHTML樣式)滾動動畫加入到Chromium中,微軟已經將該滾動動畫移植到了基于Chromium的Edge瀏覽器的Dev Canary通道中。默認情況下,Edge瀏覽器中啟用了脈沖樣式的滾動動畫。對于Chrome,該功能可能會在未來幾天內出現在試驗版瀏覽器中。
微軟表示,Impulse-style (也就是EdgeHTML-style)滾動動畫將提供更靈敏的滾動體驗,用戶啟用后鼠標滾輪的每個刻度都試圖模仿基于物理的內容,內容會開始快速移動然后逐漸變慢。換句話說,由于開始時的快速加速,該模式會給人一種更靈敏的感覺。
此外微軟還在推行另一項稱之為“percent-based scrolling”(基于百分比的滾動)的滾動方案,該模式允許瀏覽器將鼠標滾輪或者鍵盤滾動解釋為預期滾動條的百分比。微軟目前正努力將經典版Edge瀏覽器的優秀特性移植到Chromium平臺上,包括這項基于百分比的滾動方式。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。