[jQuery]改良fadeToggle且無法在切換中動作

  • 964
  • 0

摘要:[jQuery]改良fadeToggle且無法在切換中動作

本來想說用純jQuery可以很方便地做效果,

但是遇到萬惡的表格(table)後,就發生了許多問題......

因為我實在捨不得用<ul><li>取代table,於是還是研究了一下怎麼改善fade功能。

首先看一下我發生問題的範例(請點擊連結忘記密碼與切換後的返回按紐測試):

https://googledrive.com/host/0B7hg_8WvMyfJfkFrVVBGaTdlb09MUkViMllzOWlZYlRuZEFlOEdVMVpVQm9KSTh5Qjh3VEE/index1.html

你會發現原本藏在下面的表格欄位先出現然後才隱藏上面的表格欄位,看起來非常的不自然!(我是用crome瀏覽器)

於是我改良了一下變成這樣(請點擊連結忘記密碼與切換後的返回按紐測試):

https://googledrive.com/host/0B7hg_8WvMyfJfkFrVVBGaTdlb09MUkViMllzOWlZYlRuZEFlOEdVMVpVQm9KSTh5Qjh3VEE/index2.html

看起來比較順眼了?然而他還是有bug!但這bug是jQuery的fade也有的。因為fade系列說穿了只是改透明度,

因此用這個點來創建一個新的function:


function fade(obj1,obj2,sec){
	var t;
	var k=1;
	var q=(10*sec);
	var hideId;
	var showId;
	if($("#"+obj1).css("display")=="none"){
		hideId=obj2; showId=obj1;
	}else{
		hideId=obj1; showId=obj2;
	}
	tmp();
	function tmp(){
		if(k<(10*sec)){
			$("#"+hideId).css({ opacity: 1/k });
			k++;
			t=setTimeout(tmp, 100);
		}else{
			$("#"+showId).css({ opacity: 0.0 });
			$("#"+showId).css({ display: "table-row" });
			$("#"+hideId).css({ opacity: 0.0 });
			$("#"+hideId).css({ display: "none" });
			if(q>=1){
				$("#"+showId).css({ opacity: 1/q });
				q--;
				t=setTimeout(tmp, 100);
			}else{
				$("#"+showId).css({ opacity: 1.0 });
				clearTimeout(t);
			}
		}
	}
}

這個方法的obj1與obj2的順序沒有關係,因為程式已經做了判斷哪個是被隱藏的、哪個是要顯示出來的,因此這個方法是fadeToggle的改良版。

後面的sec是秒數為單位,你可以不用這個參數,並且做微調,原方法是隱藏與顯示花多少時間(以1/10為單位,因為透明度是小數),

若sec=2則總共過了4秒完成切換的動作(範例是1也就是過2秒)。

因此就是利用timer改變透明度,hideId的透明度是越來越小,而showId的透明度是越來越大,不過他們有順序性,所以沒有重疊的效果。

若要重疊的效果就要再修改囉(先隱藏一個再顯示另一個,而不是一邊隱藏一個再一邊顯示另一個)~

到這邊看起來一切很合理,但是當你試著快按作用的按鈕或連結時,發現timer不聽使喚了!

還有jQuery的fade也有的問題:當你切換時仍然可以做動作。

這個可能可以用其他方式修改,但既然我們要自己做改良版,就自己修改看看囉~

思考方向:

1.防止使用者重複按:用一個變數當flag當使用者按兩次以上不會執行重複動作。

2.用一個'mask'蓋住作用範圍,等到切換完成再拿掉mask,使用者才能進行操作。

第一個應該很好理解,不過方法沒有很十全十美,因此flag我還是把它拿出來了(沒有在function裡面設)。

第二個可以看下面的範例(請點擊連結忘記密碼與切換後的返回按紐測試):

https://googledrive.com/host/0B7hg_8WvMyfJfkFrVVBGaTdlb09MUkViMllzOWlZYlRuZEFlOEdVMVpVQm9KSTh5Qjh3VEE/index3.html

因此在html要有一個當mask的範圍div:


<div id="mask" style="background: rgba( 255, 255, 255, 0.0 );display:none;position:absolute;z-index:1000px;"></div>

這個div的style應該依照你的需求修改,假如你要整頁停止動作(切換時不只切換的範圍,包括整個網頁畫面都不能動),

可以參考這個網頁:

http://tjvantoll.com/2013/04/24/showing-a-css-based-loading-animation-while-your-site-loads/

因此function修改成這樣:


var prevent=true;										// prevent user click too much times
function fade(obj1,obj2,sec){
	var t;
	var k=1;
	var q=(10*sec);
	var hideId;
	var showId;
	if($("#"+obj1).css("display")=="none"){
		hideId=obj2; showId=obj1;
	}else{
		hideId=obj1; showId=obj2;
	}
	if(prevent){ prevent=false;
		$("#mask").css("width",$("#"+hideId).width()+"px");
		$("#mask").css("height",$("#"+hideId).height()+"px");
		$("#mask").css("left",$("#"+hideId).offset().left+"px");
		$("#mask").css("top",$("#"+hideId).offset().top+"px");
		$("#mask").css("display","block");
		tmp();
		function tmp(){
			if(k<(10*sec)){
				$("#"+hideId).css({ opacity: 1/k });
				k++;
				t=setTimeout(tmp, 100);
			}else{
				$("#"+showId).css({ opacity: 0.0 });
				$("#"+showId).css({ display: "table-row" });
				$("#"+hideId).css({ opacity: 0.0 });
				$("#"+hideId).css({ display: "none" });
				$("#mask").css("width",$("#"+showId).width()+"px");
				$("#mask").css("height",$("#"+showId).height()+"px");
				$("#mask").css("left",$("#"+showId).offset().left+"px");
				$("#mask").css("top",$("#"+showId).offset().top+"px");
				if(q>=1){
					$("#"+showId).css({ opacity: 1/q });
					q--;
					t=setTimeout(tmp, 100);
				}else{
					$("#"+showId).css({ opacity: 1.0 });
					prevent=true;
					$("#mask").css("display","none");
					clearTimeout(t);
				}
			}
		}
	}
}

最後我們的結果就是這樣(請點擊連結忘記密碼與切換後的返回按紐測試):

https://googledrive.com/host/0B7hg_8WvMyfJfkFrVVBGaTdlb09MUkViMllzOWlZYlRuZEFlOEdVMVpVQm9KSTh5Qjh3VEE/

 

原始檔下載:FadeModify.zip