jquery外掛——點選交換元素位置(帶動畫效果)

技術mix呢發表於2017-09-07

一、需求的誕生

  在我們的網頁或者web應用中,想要對列表中的元素進行位置調整(或者說排序)是一個常見的需求。實現方式大概就以下兩種,一種是帶有類似“上移”、“下移”的按鈕,點選可與相鄰元素交換位置,另一種便是通過拖拽進行排序。搜尋“jquery拖拽排序外掛”,你會看到相關外掛層出不窮。在HTML5拖拽API完善再加上移動裝置橫行的今天,後者似乎更受青睞,因為它有更簡潔的操作,你看看,拖來拖去就可以調整順序,多炫啊。

  但是!為什麼要說但是呢,因為這種拖拽操作也有它的弊端。首先是功能不明顯,使用者進來你的頁面後不知道原來這些東西是可以拖動的,除非你再旁邊加一行說明“拖動這些圖片可以進行排序”;其次,拖動操作沒有你想象的那麼容易,使用PC的使用者可能會在拖動的時候全選了一行文字,或是放不到正確的地方,而使用平板的使用者呢,可能進行上下拖動的時候頁面跟著一起滾動了,發揮想象一下。。。真的,多笨的使用者都是有的。

  所以。。。萬能的產品經理大手一揮,這裡,我們要通過點選排序!首先“上移”“下移”兩個按鈕擺那,你一看就知道可以移動,其次,如果連按鈕都點不準,那以你的智商還玩什麼電腦~

  我們在填一些表單的時候,這樣的點選排序功能確也見過很多了,那我這裡為什麼還要再重新造輪子呢!其實只為一個理由:他們那些沒有動畫效果。點選移動的時候“噌”一下就換過去了,如果交換的兩個元素樣子差不多,使用者根本看不出來已經換過位置了。所以,我要讓他有動畫,要讓使用者清楚的知道,交換位置確實發生了。這樣使用者就會感覺自己很聰明,“我點的還是很準的嘛~”,一個小細節,打動使用者了~

二、外掛使用及效果展示

  我總喜歡先把騾子拉出來溜溜,那麼,來看看如何使用吧:

  html程式碼如下:

<ul class="sortablelist">
  <li class="sortableitem">
    <span>1</span><span class="moveup">up</span><span class="movedown">down</span>
  </li>
  <li class="sortableitem">
    <span>2</span><span class="moveup">up</span><span class="movedown">down</span>
  </li>
  <li class="sortableitem">
    <span>3</span><span class="moveup">up</span><span class="movedown">down</span>
  </li>
  <li class="sortableitem">
    <span>4</span><span class="moveup">up</span><span class="movedown">down</span>
  </li>
</ul>

  js程式碼如下:

$('.sortablelist').clickSort();

  css程式碼如下:

.sortableitem span{display:inline-block;width:100px;}
.sortablelist{position:relative;}
.sortableitem{position:relative;width:400px; border:1px solid red; margin:30px;}

  執行效果如下:

  • 1updown
  • 2updown
  • 3updown
  • 4updown

三、技術細節

  其實我真正想說的是這一部分內容,就是交換動畫的製作。其核心就是使用jquery的animated方法,但是具體怎麼個用法還是經過一番考慮的。

  大家都知道,animate的動畫效果其實是通過動態修改css的屬性值來產生漸變效果的。然而我們在交換兩個節點的位置時,其實並未操作元素的css屬性。所有的變化僅僅是由

<li>1</li>
<li>2</li>

變為了

<li>2</li>
<li>1</li>

  根本沒有操作css屬性嘛!這讓我怎麼漸變?而且交換兩個元素的位置從來都是瞬時完成的,壓根沒有“緩緩交換”這麼一說。

  所以就需要變通了,能不能從視覺上”欺騙“一下使用者呢?先給他一個兩個元素移動交換位置的假象,然後再悄悄把元素的位置”瞬時交換“。恩,不錯的想法!

  首先,我們選擇要漸變的屬性,當然是非top莫屬了,通過animate操作top屬性來完成上下移動。top屬性只有在元素的相對定位或是絕對定位時才有效,所以我們在css中為其父容器(sortablelist)及需要移動的子元素(sortableitem)全部指定position:relative。當我對我的想法躍躍欲試的時候,發現了一個問題:當我把第一個li的top值設為40px,第二個li的top值設為0的時候,兩個li的位置並沒有發生交換,而是這樣的

  2下來了,但是1卻沒有上去。為什麼呢?道理很簡單:相對定位的元素,偏移出來的位置不能被其他元素佔據。那我豈不要用absolute了?但是如果使用absolute的話效果確實這樣的:

  1和2的位置被其他不速之客佔據了!看來想要修改元素的位置並不是那麼順利啊,被交換的元素是不能走的,它一走就被別人佔了地盤了。那怎麼辦呢?真身不能走,讓替身來完成交換動畫如何?我真是個天才~關鍵時刻,jquery的clone()方法派上用場了,讓它克隆一個替身出來,給替身absolute,讓替身去動畫去,動畫開始的時候自己先隱藏,等動畫完了悄悄”瞬間交換“位置,然後再出現。這簡直是一臺魔術秀。臺下的觀眾都以為:哇,交換位置了耶,還帶動畫耶!

  所以呢,css中指定的relative的作用你也明白了吧。使用的時候千萬別去掉哦。html程式碼中的class名字也要保持不變,你可以在li元素中再新增其他元素用於定製自己的介面。

四、外掛配置引數

  我想了想也沒想到有什麼引數可以配置,暫時只加了一個speed,預設是200,控制動畫的速度,另外有一個回撥函式callback,在每次交換完畢的時候執行。如下

$('.sortablelist').clickSort({
    speed:1000,
  callback:function(){
    alert('ok');
    }
});

   最後奉上下載地址:http://files.cnblogs.com/lvdabao/jquery.clickSort.js

相關文章