本篇文章主要講查找並分析bug的思路,相關的函數不是本文的重點。
眾所周知,setTimeout和setInterval是用來做延遲調用以及周期性調用的方法,他們支持的參數都差不多。
setTimeout/setInterval的第一個參數為回調函數,可以是一個方法名,也可以是一個匿名函數。第二個參數就是延遲執行的時間,單位ms。
我們可以這樣用:
setTimeout(fn,1000); function fn(){}; //還可以這樣用 setTimeout(function(){},1000); //interval一樣
我們demo上設置的延遲時間是1000ms,由於js是單線程的,實際的延遲時間可能會比 1000ms長,但是只要進程空閑時就會立即執行。(這也是為什么建議使用setTimeout來代替setInterval的原因)
好了,方法都解釋的差不多了,直插主題吧。
一個簡單的需求,當用戶輸入錯誤時顯示一個tips,並在x秒后隱藏,超級簡單對不對,開搞。
function hide(){ //do hide } setTimeout(hide,5000)//在5000ms后做hide操作
uc,qq,chrome,什么國產手機自帶瀏覽器都跑一遍吧,沒任何問題,只有ios7的safari,如果一直滑動的話,不會執行延遲操作,只有停止滑動才會執行,而且是立即執行(大概延遲800ms左右)
比較棘手啊,這種情況有點像在有些瀏覽器上滑動時,gif動圖會停止運動(有遇到過頁面滑動,js動畫都停止的),猜測會不會是一種優化手段呢,於是
var count =0,startTime=new Date().getTime(),endTime; timer=setTimeout(function(){ //endTime = new Date().getTime(); var a = document.createElement("p"); a.innerText = endTime-startTime; document.getElementById("demo").appendChild(a) alert("ok"); },2000) window.addEventListener("touchend",function(){ endTime = new Date().getTime(); count+=1; var a = document.createElement("p"); a.innerText = startTime+"---"+endTime; document.getElementById("demo").appendChild(a) },false)
開始監聽的是touchmove事件,證明滑動不會影響除延時函數以外的其他js執行。
監聽touchend事件,滑動結束后並不是2000ms執行回調,測試大概是800ms左右。
根據上面的測試,我們能大概的來猜測下,ios7中safari做了滑動優化,在滑動的過程中阻止延遲事件的執行,在滑動結束后再執行。
解決方法
其實這種情況,沒什么好解決的(不要打我),因為ios7的確是很老的系統了。但是我們為了精益求精還是得研究下的。
1.由於是滑動造成的,那我們直接干掉滑動吧,在hide以后再開啟(在tips消失之前滑動不了頁面)
2.做一個兼容,如果用戶滑動了,記錄滑動的開始時間和move時間,兩個的差值如果大於延遲時間就直接執行回調
時間倉促,寫的有點匆忙(今天星期五啊。。),如果有什么遺漏或者錯誤的地方歡迎指出
