2012-10-12 34 views
14

Tôi nhận thấy hành vi kỳ lạ này với iOS mới nhất (iOS 6). Nếu gọi một hàm cho bất kỳ sự kiện cảm ứng nào có một setTimeout bên trong, phần bên trong setTimeout sẽ không bao giờ được kích hoạt.iOS 6 js sự kiện chức năng không được gọi là nếu có setTimeout trong nó

Điều này chỉ xảy ra khi có "hoạt ảnh hệ thống" chẳng hạn như cuộn và phóng to/thu nhỏ.

Ví dụ:

http://jsfiddle.net/p4SdL/2/

(tôi đã sử dụng jquery chỉ để thử nghiệm nhưng tương tự xảy ra với js tinh khiết)

mở trang đó với safari trên bất kỳ thiết bị iOS 6 và phóng to hoặc thu . Cảnh báo sẽ không bao giờ được gọi.

Nếu được thử nghiệm trên bất kỳ thiết bị iOS 5 nào, tính năng này sẽ hoạt động tốt! Dường như trong các hoạt ảnh này, setTimeout hoặc setInterval được thiết lập lại bởi hệ điều hành. Đây có phải là hành vi dự định hoặc lỗi không?

Cảm ơn

Trả lời

16

Note: Dường như UIWebView không hỗ trợ requestAnimationFrames. Cảm ơn Guillaume Gendre vì đã chỉ ra!

Chúng tôi đã gặp sự cố tương tự với ứng dụng web mà chúng tôi đang nghiên cứu.

Đối với chúng tôi, đó là touchmove gây ra sự cố. Chúng tôi đã thực hiện một giải pháp thay thế (được tìm thấy ở đây: https://gist.github.com/3755461) dường như hoạt động khá tốt cho đến khi một vấn đề khác buộc chúng tôi phải từ bỏ nó. (Tôi đã thử thêm các workaround để fiddle của bạn và đã có thể có được bộ đếm thời gian để bắn một hoặc hai lần, nhưng nó đòi hỏi một cử chỉ lạ + di chuyển sự kiện đó là damn gần như không thể tái sản xuất liên tục.)

Dù sao, một trong những các tính năng mới trong iOS 6 dành cho nhà phát triển là requestAnimationFrames. Cách giải quyết của tôi về cơ bản là một trình bao bọc cho bộ tính giờ, cho phép nhà phát triển chuyển một boolean, sẽ gọi hàm gốc hoặc hàm workaround.

Ví dụ:

setTimeout(function(){alert("HI")}, 1000); // using native 
setTimeout(function(){alert("HI")}, 1000, true); // using workaround 

Dưới đây là cách bổ sung để sử dụng workaround:

setInterval(function(){console.log("Interval")}, 1000, true); 

var timer = setTimeout(function(){ /* ... */ }, 60000, true); 
clearTimeout(timer); 

var interval = setInterval(someFunc, 10000, true); 
if(someCondition) clearInterval(interval); 

Dưới đây là hai fiddles với các ví dụ workaround. Hãy thử nhúm/phóng to trên các ô vuông màu đen:

http://jsfiddle.net/xKh5m/embedded/result (Sử dụng bản địa setTimeout chức năng) http://jsfiddle.net/ujxE3/embedded/result

Chúng tôi đã sử dụng workaround này trong một vài tháng trong một môi trường sản xuất, và đã không chạy vào bất kỳ vấn đề lớn .

Dưới đây là một ý chính công cộng của workaround: https://gist.github.com/4180482

Dưới đây là thông tin về requestAnimationFrames:

MDN documentation

Paul Irish on requestAnimationFrame

Chúc may mắn!

+0

cảm ơn câu trả lời rất chi tiết của bạn nhưng như bạn đã đề cập, đây không phải là giải pháp đúng cho vấn đề của tôi. Nhưng bây giờ, tôi nghĩ rằng đây là một lỗi được giới thiệu trong iOS6 và không phải là một số tính năng mới. – kiwi1342

+0

Trông giống như một giải pháp cho tôi. –

+1

Điều này là rất lớn, đã cứu tôi một nhức đầu chắc chắn. Nhiều người cần xem giải pháp này – eivers88

Các vấn đề liên quan