分享有關(guān)jQuery中animate、slide、fade等動畫的連續(xù)觸發(fā)、滯后反復(fù)執(zhí)行的bug
我寫文章的風(fēng)格就是喜歡在開頭講問題法傷的背景:
因為最近要做個操作選項的呼出,然后就想到了用默認隱藏,鼠標劃過的時候顯示的方法。
剛開始打算添加一個class="active",直接觸發(fā)mouseover(或者mouseenter)的時候add,mouseout(或者mouseleave)的時候remove,這個解決方法很簡單,也很實用,但是體驗上可能不是那么酷炫(好吧,這個詞用的,瞬間感覺好low?。跃拖氲搅擞胊nimate或者slide這些jQuery的動畫,然后一開始講真,這個插件自己寫,會碰到些問題,不太好實現(xiàn)(畢竟js掌握的不是很到位),然后聽同事講去找找jquery,導(dǎo)入后直接引用就可以了。
(還好我沒養(yǎng)成一碰到要做某個特效,第一反應(yīng)是網(wǎng)上找插件,說起這個,又想到前幾天碰到的關(guān)于將table中的表頭對界面滾動而固定的那個解決方法了,過幾天傳上來,講真,那個方法網(wǎng)上找了一圈沒找到合適的解決方法,最后我自己想了個方法,還是蠻有成績感的,雖然有可能不是最優(yōu)的解決方案)
回到正題,網(wǎng)上找了一圈,講真,別人的插件,做的確實很贊,而且各種瀏覽器下的兼容性也解決了,不過我個人而言,只在兩三個頁面用到,而且又要導(dǎo)入文件(這個好像不是特別麻煩),又要用別人的,終歸沒什么成就感。
然后,最后還是自己動手寫了,雖然花了點時間,也碰到了一些問題,不過還是不錯的,問題也最后解決了,至少對幾個jQuery的內(nèi)置函數(shù)又熟悉了一點。
ps:最后補充一句,在我自己找出解決方案后,再次百度了一下,好吧,出來的第一個網(wǎng)頁鏈接,點進去就是我所用的方法。
bug重現(xiàn):原本想做個動圖的,好像太麻煩了,還是上代碼吧,知道這個問題的應(yīng)該不用看動圖也知道是個怎么樣的問題;不知道這個問題的,可以先把代碼拷貝下來試一下。
PS:下面以animate動畫為例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>test</title>
<meta charset="utf-8">
<link rel="stylesheet" href="./bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="./font-awesome/css/font-awesome.min.css">
<script src="./bootstrap/js/jquery-1.11/jquery.min.js"></script>
<script src="./bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
<div style="width:70%;margin:50px auto;height:300px;">
<div id="test" style="width:900px;height:100px;border:1px solid red;overflow:hidden;">
<div class="test" style="margin-left:-6em">
<a>
測試用的文字
<i class="fa fa-arrow-right"></i>
</a>
</div>
</div>
</div>
<script>
$("[data-toggle='tooltip']").tooltip();
$("#test").on("mouseover",function(){
var $this = $(this);
var $thisTest = $this.find("div.test");
$thisTest.css("position","relative");
// $thisTest.stop();
$thisTest.filter(':not(:animated)').animate({marginLeft:"0em"});
})
.on("mouseout",function(){
var $this = $(this);
var $thisTest = $this.find("div.test");
$thisTest.css("position","relative");
// $thisTest.stop();
$thisTest.filter(':not(:animated)').animate({marginLeft:"-6em"});
})
//連續(xù)觸發(fā)動畫bug
//不允許動畫累積;或是在新的動畫開始前,先停止當(dāng)前正在進行的動畫
</script>
</body>
</html>
上面這份代碼,stop()這個方法被我注釋掉了,是我個人認為最完美的解決方法,沒有被注釋掉的,是我后來百度了一下后,別人提到的另一種解決方案,但我個人感覺不是特別完美,至于差別我在后面提。
最開始,
$thisTest.filter(':not(:animated)').animate({marginLeft:"0em"});
$thisTest.filter(':not(:animated)').animate({marginLeft:"-6em"});
這兩句代碼,是沒有filter()函數(shù)的,也就是最開始碰到這個bug的時候的代碼的樣子。
這個bug產(chǎn)生原因就是事件在短時間內(nèi)(上一個動畫未播放完),動畫累積導(dǎo)致的(估計碰到這個問題的,回過頭去看看代碼都知道這個原因)。所以,解決的方法,有兩個。
【filter】
一個就是用filter過濾,在動畫發(fā)生前,過濾掉正在進行動畫的元素,只讓上一個動畫已經(jīng)結(jié)束的元素才能觸發(fā)新的事件。
然后這就帶來一個新問題了,當(dāng)我把鼠標移至對應(yīng)的內(nèi)容上,mouseover事件觸發(fā),這個時候,在動畫還未結(jié)束的時候,我再將鼠標移除對應(yīng)內(nèi)容區(qū)域外,mouseleave事件觸發(fā),但是因為上一個動畫還未結(jié)束,所以即使觸發(fā)了該事件,但預(yù)期的函數(shù)并未執(zhí)行,此時預(yù)期中的“mouseleave事件觸發(fā),內(nèi)容隱藏”結(jié)果便無法做到了。
當(dāng)然,如果操作者在mouseover事件觸發(fā)的動畫結(jié)束前,鼠標一直停在對應(yīng)內(nèi)容上,這個方案并不會有影響。
【stop】
對于stop(),雖然知道這是大家都了解的,還是再搬一遍吧。
//語法結(jié)構(gòu)
$("#div").stop();//停止當(dāng)前動畫,繼續(xù)下一個動畫
$("#div").stop(true);//清除元素的所有動畫
$("#div").stop(false, true);//讓當(dāng)前動畫直接到達末狀態(tài) ,繼續(xù)下一個動畫
$("#div").stop(true, true);//清除元素的所有動畫,讓當(dāng)前動畫直接到達末狀態(tài)
這個方案的思路,就是簡單的:當(dāng)我mouseover的時候,觸發(fā)對應(yīng)的動畫,但是在動畫還未結(jié)束的時候,我卻要mouseleave,同時觸發(fā)mouseleave對應(yīng)的動畫,這個時候我便需要停止對應(yīng)元素正在進行的動畫。然后,這個bug也就不存在了。
最后,好吧,這篇隨筆好像也沒啥總結(jié)的,其實就是對animate、slide、fade動畫函數(shù)的熟悉吧,同時再熟悉一下stop有參數(shù)無參數(shù)的區(qū)別(講真,剛開始沒想到用stop,過了一兩天后,偶然看到API的時候,看到了stop,才突然有了用stop解決這個bug的設(shè)想)。
以上所述是腳本之家小編給大家分享有關(guān)jQuery中animate、slide、fade等動畫的連續(xù)觸發(fā)、滯后反復(fù)執(zhí)行的bug,希望對大家今后的工作學(xué)習(xí)有所幫助。
相關(guān)文章
Html5的placeholder屬性(IE兼容)實現(xiàn)代碼
Placeholder是HTML5新增的另一個屬性,當(dāng)input或者textarea設(shè)置了該屬性后,該值的內(nèi)容將作為灰字提示顯示在文本框中,當(dāng)文本框獲得焦點時,提示文字消失。以前要實現(xiàn)這效果都是用JavaScript來控制才能實現(xiàn) , firefox、google chrome等表示對其支持 , 唯獨IE不支持2014-08-08
淺析jQuery Ajax請求參數(shù)和返回數(shù)據(jù)的處理
這篇文章主要介紹了淺析jQuery Ajax請求參數(shù)和返回數(shù)據(jù)的處理的相關(guān)資料,需要的朋友可以參考下2016-02-02
jQuery實現(xiàn)模仿微博下拉滾動條加載數(shù)據(jù)效果
這篇文章主要介紹了jQuery實現(xiàn)模仿微博下拉滾動條加載數(shù)據(jù)效果,涉及jQuery響應(yīng)下拉滾動事件動態(tài)操作頁面元素的技巧,需要的朋友可以參考下2015-12-12
jquery實現(xiàn)的讓超出顯示范圍外的導(dǎo)航自動固定屏幕最頂上
經(jīng)常會遇到這樣的情況,當(dāng)頁面展示內(nèi)容過長時,想點導(dǎo)航切換欄目,就得把滾動條拉回到頂上,這樣操作總不太人性化,能不能讓導(dǎo)航超出顯示范圍外時自動貼在屏幕最頂上呢?答案肯定是能的。如果不太明白,把滾動條拉到下面點,看下我博客是效果就明白了。2011-09-09

