分享有關(guān)jQuery中animate、slide、fade等動(dòng)畫的連續(xù)觸發(fā)、滯后反復(fù)執(zhí)行的bug
我寫文章的風(fēng)格就是喜歡在開頭講問題法傷的背景:
因?yàn)樽罱鰝€(gè)操作選項(xiàng)的呼出,然后就想到了用默認(rèn)隱藏,鼠標(biāo)劃過的時(shí)候顯示的方法。
剛開始打算添加一個(gè)class="active",直接觸發(fā)mouseover(或者mouseenter)的時(shí)候add,mouseout(或者mouseleave)的時(shí)候remove,這個(gè)解決方法很簡(jiǎn)單,也很實(shí)用,但是體驗(yàn)上可能不是那么酷炫(好吧,這個(gè)詞用的,瞬間感覺好low啊),所以就想到了用animate或者slide這些jQuery的動(dòng)畫,然后一開始講真,這個(gè)插件自己寫,會(huì)碰到些問題,不太好實(shí)現(xiàn)(畢竟js掌握的不是很到位),然后聽同事講去找找jquery,導(dǎo)入后直接引用就可以了。
(還好我沒養(yǎng)成一碰到要做某個(gè)特效,第一反應(yīng)是網(wǎng)上找插件,說起這個(gè),又想到前幾天碰到的關(guān)于將table中的表頭對(duì)界面滾動(dòng)而固定的那個(gè)解決方法了,過幾天傳上來,講真,那個(gè)方法網(wǎng)上找了一圈沒找到合適的解決方法,最后我自己想了個(gè)方法,還是蠻有成績(jī)感的,雖然有可能不是最優(yōu)的解決方案)
回到正題,網(wǎng)上找了一圈,講真,別人的插件,做的確實(shí)很贊,而且各種瀏覽器下的兼容性也解決了,不過我個(gè)人而言,只在兩三個(gè)頁面用到,而且又要導(dǎo)入文件(這個(gè)好像不是特別麻煩),又要用別人的,終歸沒什么成就感。
然后,最后還是自己動(dòng)手寫了,雖然花了點(diǎn)時(shí)間,也碰到了一些問題,不過還是不錯(cuò)的,問題也最后解決了,至少對(duì)幾個(gè)jQuery的內(nèi)置函數(shù)又熟悉了一點(diǎn)。
ps:最后補(bǔ)充一句,在我自己找出解決方案后,再次百度了一下,好吧,出來的第一個(gè)網(wǎng)頁鏈接,點(diǎn)進(jìn)去就是我所用的方法。
bug重現(xiàn):原本想做個(gè)動(dòng)圖的,好像太麻煩了,還是上代碼吧,知道這個(gè)問題的應(yīng)該不用看動(dòng)圖也知道是個(gè)怎么樣的問題;不知道這個(gè)問題的,可以先把代碼拷貝下來試一下。
PS:下面以animate動(dòng)畫為例
<!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> 測(cè)試用的文字 <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ā)動(dòng)畫bug //不允許動(dòng)畫累積;或是在新的動(dòng)畫開始前,先停止當(dāng)前正在進(jìn)行的動(dòng)畫 </script> </body> </html>
上面這份代碼,stop()這個(gè)方法被我注釋掉了,是我個(gè)人認(rèn)為最完美的解決方法,沒有被注釋掉的,是我后來百度了一下后,別人提到的另一種解決方案,但我個(gè)人感覺不是特別完美,至于差別我在后面提。
最開始,
$thisTest.filter(':not(:animated)').animate({marginLeft:"0em"}); $thisTest.filter(':not(:animated)').animate({marginLeft:"-6em"});
這兩句代碼,是沒有filter()函數(shù)的,也就是最開始碰到這個(gè)bug的時(shí)候的代碼的樣子。
這個(gè)bug產(chǎn)生原因就是事件在短時(shí)間內(nèi)(上一個(gè)動(dòng)畫未播放完),動(dòng)畫累積導(dǎo)致的(估計(jì)碰到這個(gè)問題的,回過頭去看看代碼都知道這個(gè)原因)。所以,解決的方法,有兩個(gè)。
【filter】
一個(gè)就是用filter過濾,在動(dòng)畫發(fā)生前,過濾掉正在進(jìn)行動(dòng)畫的元素,只讓上一個(gè)動(dòng)畫已經(jīng)結(jié)束的元素才能觸發(fā)新的事件。
然后這就帶來一個(gè)新問題了,當(dāng)我把鼠標(biāo)移至對(duì)應(yīng)的內(nèi)容上,mouseover事件觸發(fā),這個(gè)時(shí)候,在動(dòng)畫還未結(jié)束的時(shí)候,我再將鼠標(biāo)移除對(duì)應(yīng)內(nèi)容區(qū)域外,mouseleave事件觸發(fā),但是因?yàn)樯弦粋€(gè)動(dòng)畫還未結(jié)束,所以即使觸發(fā)了該事件,但預(yù)期的函數(shù)并未執(zhí)行,此時(shí)預(yù)期中的“mouseleave事件觸發(fā),內(nèi)容隱藏”結(jié)果便無法做到了。
當(dāng)然,如果操作者在mouseover事件觸發(fā)的動(dòng)畫結(jié)束前,鼠標(biāo)一直停在對(duì)應(yīng)內(nèi)容上,這個(gè)方案并不會(huì)有影響。
【stop】
對(duì)于stop(),雖然知道這是大家都了解的,還是再搬一遍吧。
//語法結(jié)構(gòu) $("#div").stop();//停止當(dāng)前動(dòng)畫,繼續(xù)下一個(gè)動(dòng)畫 $("#div").stop(true);//清除元素的所有動(dòng)畫 $("#div").stop(false, true);//讓當(dāng)前動(dòng)畫直接到達(dá)末狀態(tài) ,繼續(xù)下一個(gè)動(dòng)畫 $("#div").stop(true, true);//清除元素的所有動(dòng)畫,讓當(dāng)前動(dòng)畫直接到達(dá)末狀態(tài)
這個(gè)方案的思路,就是簡(jiǎn)單的:當(dāng)我mouseover的時(shí)候,觸發(fā)對(duì)應(yīng)的動(dòng)畫,但是在動(dòng)畫還未結(jié)束的時(shí)候,我卻要mouseleave,同時(shí)觸發(fā)mouseleave對(duì)應(yīng)的動(dòng)畫,這個(gè)時(shí)候我便需要停止對(duì)應(yīng)元素正在進(jìn)行的動(dòng)畫。然后,這個(gè)bug也就不存在了。
最后,好吧,這篇隨筆好像也沒啥總結(jié)的,其實(shí)就是對(duì)animate、slide、fade動(dòng)畫函數(shù)的熟悉吧,同時(shí)再熟悉一下stop有參數(shù)無參數(shù)的區(qū)別(講真,剛開始沒想到用stop,過了一兩天后,偶然看到API的時(shí)候,看到了stop,才突然有了用stop解決這個(gè)bug的設(shè)想)。
以上所述是腳本之家小編給大家分享有關(guān)jQuery中animate、slide、fade等動(dòng)畫的連續(xù)觸發(fā)、滯后反復(fù)執(zhí)行的bug,希望對(duì)大家今后的工作學(xué)習(xí)有所幫助。
相關(guān)文章
jQuery遮罩層實(shí)現(xiàn)方法實(shí)例詳解(附遮罩層插件)
這篇文章主要介紹了jQuery遮罩層實(shí)現(xiàn)方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了jQuery遮罩層樣式及功能實(shí)現(xiàn)技巧,并附帶分析了一個(gè)簡(jiǎn)單jQuery遮罩層插件實(shí)現(xiàn)方法,需要的朋友可以參考下2015-12-12jQuery的顯示和隱藏方法與css隱藏的樣式對(duì)比
display:none和visible:hidden都能把網(wǎng)頁上某個(gè)元素隱藏起來,而jQuery的顯示和隱藏又有哪些方法,在本文將為大家詳細(xì)介紹下,感興趣的朋友不要錯(cuò)過2013-10-10jQuery晃動(dòng)層特效實(shí)現(xiàn)方法
這篇文章主要介紹了jQuery晃動(dòng)層特效實(shí)現(xiàn)方法,實(shí)例分析了animate方法與css樣式的操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03利用JQuery實(shí)現(xiàn)datatables插件的增加和刪除行功能
這篇文章給大家介紹了jquery實(shí)現(xiàn)datatables插件的增加和刪除行的功能,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下2017-01-01asp.net+jquery滾動(dòng)滾動(dòng)條加載數(shù)據(jù)的下拉控件
由于需求需要用到一個(gè)滾動(dòng)滾動(dòng)條加載數(shù)據(jù)的下拉列表(假如數(shù)據(jù)1000條,下拉列表開始只顯示100條,當(dāng)用戶下拉滾到條到最底下時(shí),再加載下一個(gè)100條,如此循環(huán))2010-06-06jQuery .tmpl(), .template()學(xué)習(xí)資料小結(jié)
昨晚無意中發(fā)現(xiàn)一個(gè)有趣的jQuery插件.tmpl(),其文檔在這里。2011-07-07Jquery AutoComplete自動(dòng)完成 的使用方法實(shí)例
jQuery的Autocomplete(自動(dòng)完成、自動(dòng)填充)插件有不少,但比較下來我感覺,還是bassistance.de的JQuery Autocomplete plugin比較強(qiáng)大,我們就來寫一些代碼感受一下。2010-03-03jQuery.validate.js表單驗(yàn)證插件的使用代碼詳解
Validate是基于jQuery的一款輕量級(jí)驗(yàn)證插件,內(nèi)置豐富的驗(yàn)證規(guī)則,這篇文章主要介紹了jQuery.validate.js表單驗(yàn)證插件的使用代碼詳解,需要的朋友可以參考下2018-10-10