Discuz功能改進-圖片幻燈片添加滑動特效

Discuz本身有圖片幻燈片效果,但卻沒有滑動特效,在User介面上其實非常不美麗,該怎麼說呢,太單調了,因為他只是像換投影片一樣,若要是圖片都相同,就會出現感覺沒有變化。


這邊一樣附上以下訊息。

※本人只翻譯成繁體中文,並修正部分文句讓臺灣這邊Discuz站長可以看更清楚,可能在修正文句上並不完美,請見諒。

※本文經過天香老師同意轉載並修正文句,若要再轉載修正文句,請先經過原作者同意,尊重原作者,原作者保留修改及調整權利。



圖片幻燈片在Discuz中是一個廣為使用的DIY模塊,幾乎每一個有在使用Discuz系統的人都會使用、看到。
支持這個功能的函數還允許模板的顯示樣式有多個樣子,它也被稱為百變幻燈片(超連結) ,舉例來講我們可以通過添加風格為slidebarup和slidebardown的元素給圖片幻燈片加上顯示前一個和後一個的幻燈片控制按鈕,也可以添加自己喜歡的控制按鈕來替代自動生成的數字控制按鈕。
但從功能上講它並也不是完全沒有缺陷,如在電腦上我們可以將滑鼠放到圖片幻燈片的數字控制按鈕上來選擇幻燈片顯示,但在iPad和手機上就沒有這麼方便。

在新浪體育網首頁(超連結)上的類似功能比較會發現,新浪體育網的圖片幻燈片在iPad及手機上可以通過手指滑動來選擇幻燈片,而Discuz的幻燈片在手指滑動時是絲毫不動的。
本文將探討如何讓它也能聽從手指滑動指揮。



(中間有參考樣式,但無法轉載,故空白。)


圖片幻燈片的功能是由static/js/common_extra.js中slideshow函數來實現。在這邊我們修改的思路是利用滾動條,參考Chris Coyier的文章 Slider with Sliding Backgrounds(超連結)。



Discuz的作法是通過每一個幻燈片的隱藏屬性來決定顯示哪一個或哪些幻燈片。這種作法並無法支援滑動的。Chris Coyier介紹的辦法是讓所有圖片都處再顯示狀態,只是用一個視窗將展示的部分侷限於此,所以才有可能用手指來指揮滑動選擇幻燈片。具體而言,圖片幻燈片是由下面多層結構組成的:

1)幻燈片:最內層是一張張幻燈片。它們具有Float=left的特性。由於包含它們的容器足夠寬,所以他們可以從左向右排成一行。

2)幻燈片容器:幻燈片的容器寬度是所有幻燈片寬度的總和。

3)滾動容器:幻燈片容器的外面是個帶滾動條的容器,它與幻燈片可視區域一樣寬,具有overflow-x=scroll的特性。因為它包含的幻燈片容器比它寬,所以它才能夠帶有橫向的滾動條。它比幻燈片可視區域略高,使得它的滾動條被隱藏於可是區域外。

4)顯示窗口:最外層是一個顯示窗口,它是幻燈片的可是區域,具有overflow=hidden的特性,所以它包含的元素在它範圍外的部分都被隱藏。

這裡要注意的是我們遵循原來模板結構來做定義,不需要用戶來額外添加層次。所需的層次會在程式運行時自動加入。

還有幾點值得一談:
1) 在電腦上我們是通過處理mousedown、scrol以及mouseup事件滾動停止後來選擇顯得圖片的,而在iPad上類似的事件則是touchstart、touchmove和touchend。

 2)具有overflow-x=scroll的特性滾動容器,使得在iPad上可以通過滑動來調節它的顯示內容。若不添加任何的滾動容器,而是讓具有overflow=hidden的特性顯示窗口直接包含在圖片容器中,那樣將導致在iPad上無法滑動。

3)滑動結束時,幻燈片的兩端添加了若干張複製的幻燈片,這樣在用戶結束滑動決定滾動的位置時,可以適當來避免顯示兩端的幻燈片。這使得用戶可一直向同一個方向划動,而幻燈片的顯示週而復始,不會因到達第一張幻燈片就無法向左滑動或是到達最後一張厚而無法向右滑動。
添加的複製幻燈片數量取至於顯示窗口同時顯示的幻燈片數量。如果顯示窗口只顯示一張,那麼我們只需要在幻燈片錢添加最後一張幻燈片的複製,並在幻燈片添加第一張幻燈片的複製。

上面的是意圖就是這種情況。

如果顯示窗口是同時顯示兩張幻燈片的話,我們就需要複製添加五張幻燈片。如下圖所示。當用戶滑動結束後,我們要顯示窗口裡左面一張的圖片綠框中。
舉例來講如果滑動結束顯示的是圖片中第二個咖啡色框框中的兩張幻燈片,我們就要往左平移三格(注意這個例子裡有三張原始的幻燈片) 代之以顯示圖片中第二個咖啡色框裡的兩張幻燈片。
這個做法目的是為了讓使用者不查詢的前提下保證在顯示兩張幻燈片的兩側都至少還有兩張幻燈片,這就使得使用者下次滑動時不會有超出幻燈片容易邊緣的問題。
(HF:說真的看到第四點我自己翻譯親手打也打到好亂XD)

還有一種修改的方式是利用CSS風格中的平移轉換,參考至Kevin Foley的文章 The JavaScript Behind Touch-Friendly Sliders(超連結)。
用這種方式的話就不需要添加滾動容易了。只要將幻燈片容器適當平移就可以使得顯示窗口中的內容不斷的變動。
和第一種方式不同的地方是滾動容器裡的內容隨著手指滑動而移位是滾動條的作用,並不需要寫代碼來實現。
而第二種方式中我們需要處理touchmove事件,在其中平移幻燈片的容器。
那麼能不能不用平移變換,而直接設置和不斷變換幻燈片容器呢?
理論上是可行的,但效果非常之差,參見 Paul Irish 的讨论 Why Moving Elements With Translate() Is Better Than Pos:abs Top/left(超連結)。
另外雖然我們在使用平移變換時做的只是簡單的橫向滑動,但用的是三圍平移函數而不是二維平移函數,其原因是只有前者才會啟動硬體加速,讓滑動效果更好,參見 Guil Hernandez的評論(超連結)。

中間是幻燈片的範例,在電腦上看和彼岸網首頁右下方的日誌圖片幻燈片幾乎無差別,但在iPad就會發現它可以用手指滑動!

 (中間有幻燈片範例,但無法轉載故不顯示。)

<div class="module cl slidebox">
<ul class="slideshow"> 
 [loop] 
 <li style="width: {picwidth}px; height: {picheight}px;">
<a href="{url}"{target}>
<img src="{pic}" width="{picwidth}" height="{picheight}" />
</a>
<span class="title">{title}</span>
</li> 
[/loop]
 </ul>  
</div>  
<script type="text/javascript"> 
runslideshow(); 
 </script>

 (中間有幻燈片範例,但無法轉載故不顯示。)

<div class="module cl slidebox" slidenum="3" slidestep="1">
<div class="slidebarup" style="float: left; width: 20px; height: 80px;">
<input type="button" style="background: url(static/image/common/arw_l.gif) no-repeat; margin-top: 30px;" >
</input>
</div>
<div style="float: left; width: 240px; height: 80px; ">
<ul class="slideshow"> 
[loop] 
 <li style="width: {picwidth}px; height: {picheight}px; float: left;">
<a href="{url}"{target}><img src="{pic}" width="{picwidth}" height="{picheight}" />
</a>
<span class="title">{title}</span>
</li> 
 [/loop]  
</ul>  
</div>  
<div class="slidebardown" style="float: left; width: 20px; height: 80px;">
<input type="button" style="background: url(static/image/common/arw_r.gif) no-repeat; margin-top: 30px;" >
</input>
</div>  
</div>  
<script type="text/javascript">
  runslideshow();  
</script>

檔案下載:http://www.bian-wang.com/discuz/data/userupload/10005/slideshow.zip
※檔案部分,目前是採用彼岸網來源,看後續是否有人需要下載下來觀看,我這邊會再另外找一個空見放看看,但是這個礙於要占用所以目前不考量。


 附錄:(原有的)幻燈模版定義的一些規則:
  1.     模版裡必須包含一個slidebox作為幻燈容器,即它包含其它與幻燈有關的元素。 
  2.     slidebox裡一般會定義一個slideshow的元素作為所有幻燈片的容器。它的每個子元素代表了一張幻燈片。如果slideshow不存在的話,那麼slidebox的每個子元素被視為一張幻燈片。
  3.     可以給slidebox添加slidenum和slidestep的屬性。在沒有這兩個設置時,每次顯示一張幻燈片。定期會自動用下一張幻燈片更換。直到顯示最後一張後,再重新開始顯示第一張。如果設置了這兩個值。則slidenum代表同時顯示的幻燈片數量,slidestep代表每次更換幻燈片的數量。在開始時顯示的是前slidenum張幻燈片,但不會定期自動更換。這兩個屬性不能只設其一,那樣的話幻燈片不顯示。
  4.     可以給slidebox添加timestep的屬性。如果幻燈片在定期自動更換的話,它是以毫秒為單位的更換頻率。缺省值是2500,即每過2.5秒更換一次。
  5.     當鼠標進入顯示的幻燈片內部後,定期更換停止。等鼠標離開後,定期更新接著進行,即便之前不定期自動更換。這意味著設有slidenum和slidestep的幻燈只要鼠標進入並離開圖片區域後就會開始定期自動更換。
  6.     還可以給slidebox添加一個mevent的屬性,它的值可以為click和mouseover。它決定了用控制按鈕更換幻燈片所依據的事件。
  7.     當slidebox沒有slidenum和slidestep屬性時,可以在模版定義裡在slidebox內添加一個slidebar,其中每個元素只要不是slidebarup和slidebardown的話,就起到了一個數字控制按鈕的作用。如果沒有定義一個slidebar的話,會自動添加一個slidebar,其中包括了和幻燈片數量相同的數字控制按鈕。數字控制按鈕當有mevent定義的事件(缺省時是mouseover事件)發生時更換幻燈片。新幻燈片的選擇由該控制按鈕在slidebar裡的位置決定。
  8.     可以在slidebox內添加一個slidebarup做為前一個/上一個的控制按鈕。當有mevent定義的事件(缺省時是click事件)發生時,會更換成下一張幻燈片,或是更換slidestep張幻燈片如果slidestep設置的話。類似的還可以定義一個slidebardown做為後一個/下一個的控制按鈕。這兩個按鈕可以定義在slidebar內或外面,互不影響。
  9.     可以在slidebox裡定義一個或多個slideother。每個slideother裡應有和幻燈片數量相同的子元素,按位置與幻燈片一一對應。在對應的幻燈片顯示時它們同時顯示。


HF小補充:
HF實際參照修改調整後,Discuz幻燈片確實美觀許多也增加了滑動效果,在使用者操作上也比較美觀,但若有使用Discuz分類訊息中的模板,則出現一個小問題,部分分類訊息中的訊息會被遮住,因為目前天香公主這個調整方式是參照圖片大小去判定的,所以如果分類訊息模板中有包含文字,是會發生文字被覆蓋的問題,所以這點要多加注意,但我想如果加以CSS調整的話,應該還是可以解決的。


出處:彼岸網
作者:天香公主
翻譯及修改部分文句:HF
原網址:點我

留言

這個網誌中的熱門文章