分享有關(guān)jQuery中animate、slide、fade等動畫的連續(xù)觸發(fā)、滯后反復(fù)執(zhí)行的bug
我寫文章的風(fēng)格就是喜歡在開頭講問題法傷的背景:
因為最近要做個操作選項的呼出,然后就想到了用默認(rèn)隱藏,鼠標(biāo)劃過的時候顯示的方法。
剛開始打算添加一個class="active",直接觸發(fā)mouseover(或者mouseenter)的時候add,mouseout(或者mouseleave)的時候remove,這個解決方法很簡單,也很實用,但是體驗上可能不是那么酷炫(好吧,這個詞用的,瞬間感覺好low?。?,所以就想到了用animate或者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)頁鏈接,點進(jìn)去就是我所用的方法。
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)前正在進(jìn)行的動畫 </script> </body> </html>
上面這份代碼,stop()這個方法被我注釋掉了,是我個人認(rèn)為最完美的解決方法,沒有被注釋掉的,是我后來百度了一下后,別人提到的另一種解決方案,但我個人感覺不是特別完美,至于差別我在后面提。
最開始,
$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ìn)行動畫的元素,只讓上一個動畫已經(jīng)結(jié)束的元素才能觸發(fā)新的事件。
然后這就帶來一個新問題了,當(dāng)我把鼠標(biāo)移至對應(yīng)的內(nèi)容上,mouseover事件觸發(fā),這個時候,在動畫還未結(jié)束的時候,我再將鼠標(biāo)移除對應(yīng)內(nèi)容區(qū)域外,mouseleave事件觸發(fā),但是因為上一個動畫還未結(jié)束,所以即使觸發(fā)了該事件,但預(yù)期的函數(shù)并未執(zhí)行,此時預(yù)期中的“mouseleave事件觸發(fā),內(nèi)容隱藏”結(jié)果便無法做到了。
當(dāng)然,如果操作者在mouseover事件觸發(fā)的動畫結(jié)束前,鼠標(biāo)一直停在對應(yīng)內(nèi)容上,這個方案并不會有影響。
【stop】
對于stop(),雖然知道這是大家都了解的,還是再搬一遍吧。
//語法結(jié)構(gòu) $("#div").stop();//停止當(dāng)前動畫,繼續(xù)下一個動畫 $("#div").stop(true);//清除元素的所有動畫 $("#div").stop(false, true);//讓當(dāng)前動畫直接到達(dá)末狀態(tài) ,繼續(xù)下一個動畫 $("#div").stop(true, true);//清除元素的所有動畫,讓當(dāng)前動畫直接到達(dá)末狀態(tài)
這個方案的思路,就是簡單的:當(dāng)我mouseover的時候,觸發(fā)對應(yīng)的動畫,但是在動畫還未結(jié)束的時候,我卻要mouseleave,同時觸發(fā)mouseleave對應(yīng)的動畫,這個時候我便需要停止對應(yīng)元素正在進(jìn)行的動畫。然后,這個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)文章
jQuery遮罩層實現(xiàn)方法實例詳解(附遮罩層插件)
這篇文章主要介紹了jQuery遮罩層實現(xiàn)方法,結(jié)合實例形式較為詳細(xì)的分析了jQuery遮罩層樣式及功能實現(xiàn)技巧,并附帶分析了一個簡單jQuery遮罩層插件實現(xiàn)方法,需要的朋友可以參考下2015-12-12利用JQuery實現(xiàn)datatables插件的增加和刪除行功能
這篇文章給大家介紹了jquery實現(xiàn)datatables插件的增加和刪除行的功能,代碼簡單易懂,非常不錯,具有參考借鑒價值,需要的朋友參考下2017-01-01asp.net+jquery滾動滾動條加載數(shù)據(jù)的下拉控件
由于需求需要用到一個滾動滾動條加載數(shù)據(jù)的下拉列表(假如數(shù)據(jù)1000條,下拉列表開始只顯示100條,當(dāng)用戶下拉滾到條到最底下時,再加載下一個100條,如此循環(huán))2010-06-06jQuery .tmpl(), .template()學(xué)習(xí)資料小結(jié)
昨晚無意中發(fā)現(xiàn)一個有趣的jQuery插件.tmpl(),其文檔在這里。2011-07-07Jquery AutoComplete自動完成 的使用方法實例
jQuery的Autocomplete(自動完成、自動填充)插件有不少,但比較下來我感覺,還是bassistance.de的JQuery Autocomplete plugin比較強大,我們就來寫一些代碼感受一下。2010-03-03jQuery.validate.js表單驗證插件的使用代碼詳解
Validate是基于jQuery的一款輕量級驗證插件,內(nèi)置豐富的驗證規(guī)則,這篇文章主要介紹了jQuery.validate.js表單驗證插件的使用代碼詳解,需要的朋友可以參考下2018-10-10