WEBVTT 00:00:00.821 --> 00:00:03.421 Ta lại quay lại về cái đếm ngược Oh Noes. 00:00:03.979 --> 00:00:07.242 Giờ nếu ta muốn ảnh của Oh Noes to dần ra 00:00:07.242 --> 00:00:09.587 khi đếm ngược dần về 0, 00:00:09.587 --> 00:00:12.267 thì phải làm thế nào? 00:00:12.860 --> 00:00:15.287 Một cách làm là tạo ảnh động 00:00:15.287 --> 00:00:19.140 với CSS của ảnh này với window.setInterval. 00:00:20.663 --> 00:00:22.937 Bước đầu tiên, tôi sẽ tìm ảnh này 00:00:22.937 --> 00:00:25.142 và gán nó vào một biến. 00:00:25.167 --> 00:00:30.167 ohnoes = document.getElemenyById("ohnoes"); 00:00:32.144 --> 00:00:34.443 Ta đặt style khởi điểm, 00:00:34.443 --> 00:00:36.787 tức là sẽ bắt đầu từ chiều rộng này. 00:00:36.787 --> 00:00:39.178 Rồi ảnh sẽ lớn dần ra từ đó. 00:00:39.899 --> 00:00:44.263 Giờ ta viết một hàm makeItBigger 00:00:44.543 --> 00:00:47.641 để làm ảnh to ra từng chút một. 00:00:48.386 --> 00:00:52.738 Ở đây ta lấy giá trị style.width, 00:00:53.123 --> 00:00:58.123 lấy giá trị style.width từ trước và cộng thêm 1 vào. 00:01:00.239 --> 00:01:04.604 Cuối cùng tôi sẽ gọi hàm setInterval với hàm này. 00:01:04.604 --> 00:01:07.621 window.setInterval(makeItBigger), 00:01:07.623 --> 00:01:09.701 Ta muốn nó to lên từng nào nào? 00:01:09.701 --> 00:01:11.861 Hỏi cách khác là cứ bao lâu thì sẽ to lên 1 lần? 00:01:11.861 --> 00:01:13.881 Nếu ta ma muốn tạo một hình ảnh động thật mượt, 00:01:13.881 --> 00:01:15.378 thì tức là sẽ cần thay đổi trong khoảng tần suất 00:01:15.378 --> 00:01:18.406 24 khung hình mỗi giây tới 60 khung hình mỗi giây. 00:01:18.918 --> 00:01:23.918 Tôi sẽ thử với 30 khung hình mỗi giây, tức là 1000/3. 00:01:25.664 --> 00:01:28.343 Không được rồi. 00:01:29.007 --> 00:01:31.422 Bạn biết tại sao không? Hơi rắc rối đấy. 00:01:31.422 --> 00:01:33.963 Ta sẽ xem lại xem nào. 00:01:34.138 --> 00:01:39.074 Giá trị của ohnoes.style.width 00:01:39.074 --> 00:01:41.138 sau khi chạy dòng lệnh này là bao nhiêu nào? 00:01:41.674 --> 00:01:45.717 Chắc là 50px rồi sẽ đến 51px rồi, 00:01:45.717 --> 00:01:50.187 nhưng ta cứ log ra xem ohnoes.style.width là bao nhiêu. 00:01:50.187 --> 00:01:52.798 Ta đặt cái này vào trong infoDiv. 00:01:52.997 --> 00:01:56.304 Nó sẽ bằng... 00:01:58.522 --> 00:02:00.786 50px, okay. 00:02:00.786 --> 00:02:05.162 Rồi khi ta cộng thêm 1 vào 50px, 00:02:05.744 --> 00:02:07.903 50px thêm 1 là gì? 00:02:07.903 --> 00:02:11.398 Bạn đoán là 51px, nhưng JS 00:02:11.398 --> 00:02:15.366 coi 50px là 1 string, 00:02:16.365 --> 00:02:20.400 nên thêm 1 sẽ thành 50px1, 00:02:20.400 --> 00:02:22.635 tức là chả có ý nghĩa gì. 00:02:22.635 --> 00:02:25.955 Như vậy là trình duyệt sẽ không 00:02:25.955 --> 00:02:29.105 thay đổi thuộc tính width theo giá trị dở hơi này được rồi. 00:02:29.920 --> 00:02:33.576 Vậy là ta sẽ cần chuyển đổi string với đơn vị pixel này 00:02:33.576 --> 00:02:35.957 về kiểu số, 00:02:35.957 --> 00:02:37.743 rồi cộng 1 vào số đó, 00:02:37.743 --> 00:02:40.400 rồi lại thêm "px" vào sau. 00:02:40.984 --> 00:02:45.323 Ta có thể đặt cái này vào trong parseFloat, 00:02:45.836 --> 00:02:47.565 thế là đổi được về dạng số. 00:02:47.565 --> 00:02:50.094 Rồi ta đóng ngoặc cụm này lại, 00:02:50.260 --> 00:02:53.081 và thêm "px" vào sau. 00:02:53.081 --> 00:02:56.122 Được rồi. Ảnh đang to dần lên rồi. 00:02:57.952 --> 00:02:59.570 Bạn thấy cái lằng nhằng 00:02:59.570 --> 00:03:01.451 trong việc tạo hình động với CSS 00:03:01.451 --> 00:03:03.808 là thường nó sẽ có cả chữ đơn vị ở sau giá trị số nữa, bạn sẽ phải 00:03:03.808 --> 00:03:06.199 chuyển bỏ đơn vị đó đi... trời ơi ảnh to quá... 00:03:06.199 --> 00:03:10.039 bạn phải bỏ chữ đơn vị đó ra rồi lại đưa nó lại vào sau. 00:03:12.726 --> 00:03:14.694 Ảnh này to ra quá rồi. 00:03:14.694 --> 00:03:17.086 Còn một vài vấn đề thường gặp 00:03:17.086 --> 00:03:20.787 khi sử dụng setInterval để thay đổi thuộc tính CSS. 00:03:21.510 --> 00:03:24.249 Đầu tiên là trình duyệt sẽ không phải lúc nào cũng 00:03:24.249 --> 00:03:28.043 đợi đúng theo số interval này. 00:03:28.789 --> 00:03:31.970 Nếu có event gì khác xảy ra, như là khi người dùng sử dụng trình duyệt, 00:03:31.970 --> 00:03:35.892 gõ gì đó chẳng hạn, thì có thể trình duyệt sẽ đợi xong event đó mới gọi hàm callback này, 00:03:35.892 --> 00:03:38.411 thì hoạt hình động trông sẽ không được mượt. 00:03:39.132 --> 00:03:41.571 Thứ 2 nữa là trình duyệt sẽ gọi hàm này 00:03:41.571 --> 00:03:43.486 kể cả khi tab này ẩn đi, 00:03:43.486 --> 00:03:47.130 tức là sẽ tiêu tốn tài nguyên của máy tính. 00:03:48.409 --> 00:03:50.312 Vì vậy nên là các trình duyệt hiện đại 00:03:50.312 --> 00:03:52.065 có một hàm mới, 00:03:52.065 --> 00:03:55.630 chuyên dùng để tạo hoạt hình với DOM, 00:03:55.630 --> 00:03:58.832 gọi là window.requestAnimationFrame. 00:03:59.391 --> 00:04:02.886 Làm việc với hàm đó, đầu tiên ta sẽ bỏ dòng setInterval này đi 00:04:02.886 --> 00:04:07.886 và gọi hàm requestAnimationFrame() 00:04:09.166 --> 00:04:11.731 ở trong hàm này. 00:04:11.731 --> 00:04:15.026 Và ta sẽ chỉ nó đến 00:04:15.026 --> 00:04:18.243 hàm makeItBigger. 00:04:19.173 --> 00:04:24.118 Rồi sẽ sẽ gọi hàm makeItBigger() ngay khi tải trang web. 00:04:27.588 --> 00:04:30.690 Oh! Ảnh này đang to lên nahnh quá. 00:04:30.690 --> 00:04:34.672 Trình duyệt đang gọi hàm makeItBigger liên tục 00:04:34.672 --> 00:04:37.829 mỗi khi cập nhật ảnh, tức là vào khoảng 60 khung hình một giây, 00:04:37.829 --> 00:04:39.943 tức là gấp đôi tần số vừa rồi. 00:04:39.943 --> 00:04:43.112 Hàm này cứ mỗi lần lại cộng thêm 1px vào chiều rộng, 00:04:43.112 --> 00:04:45.271 tính toán ra thì 00:04:45.271 --> 00:04:48.078 là cộng thêm 60px mỗi giây. 00:04:48.078 --> 00:04:50.832 Chỉ vài giây là ảnh đã to hơn cả trang rồi. 00:04:50.832 --> 00:04:52.771 Giờ to quá đi mất rồi. 00:04:52.771 --> 00:04:55.777 Vậy làm sao để làm chậm hoạt hình này lại? 00:04:56.336 --> 00:04:58.541 Có một vài cách, nhưng một cách tôi thích dùng 00:04:58.541 --> 00:05:01.316 là kiểm tra xem đã chạy bao nhiêu giây rồi, 00:05:01.316 --> 00:05:03.474 rồi tính giá trị của chiều rộng 00:05:03.474 --> 00:05:05.170 dựa theo giá trị đó. 00:05:05.170 --> 00:05:09.036 Ta bắt đầu chép lại thời gian khởi điểm, tính theo ms, 00:05:09.036 --> 00:05:11.033 trước khi hàm này được gọi. 00:05:11.033 --> 00:05:14.632 var startTime... ảnh lại to ra nữa rồi. 00:05:14.632 --> 00:05:17.407 new Date().getTime(); 00:05:17.407 --> 00:05:20.866 Trong makeItBigger9) thì ta lưu giá trị của thời gian hiện tại. 00:05:20.866 --> 00:05:25.866 var currTime = new Date().getTime(); 00:05:27.007 --> 00:05:28.691 Giờ ta phải tính, 00:05:28.691 --> 00:05:31.652 ví dụ nếu muốn ảnh to ra 30px/s, 00:05:31.652 --> 00:05:34.457 và bắt đầu từ 50px, 00:05:34.457 --> 00:05:37.176 ta tính toán ở đây. 00:05:37.630 --> 00:05:42.630 newWidth bằng 50 + ..., 50 là giá trị khởi điểm... 00:05:44.452 --> 00:05:49.028 cộng thêm currentTime trừ đi startTime. 00:05:49.028 --> 00:05:50.586 Giá trị này là millisecond, nên ta sẽ 00:05:50.586 --> 00:05:53.174 chia cho 1000, 00:05:53.174 --> 00:05:57.464 rồi nhân với 30, 00:05:57.464 --> 00:06:00.058 bỏi vì ta muốn tăng lên 30px mỗi giây. 00:06:00.280 --> 00:06:02.300 Đây là newWidth rồi. 00:06:02.300 --> 00:06:07.300 Giờ ta sẽ đặt style.width cho bằng newWidth. 00:06:10.261 --> 00:06:13.976 newWidth... đây được rồi, 00:06:13.976 --> 00:06:18.976 thế này là được 30px/s thật mượt rồi. 00:06:19.967 --> 00:06:23.983 Ta có thể thay đổi số này nếu muốn nó chạy 00:06:23.983 --> 00:06:28.625 nhanh hơn chậm hơn. 00:06:31.240 --> 00:06:34.360 Còn nếu muốn dừng hoạt hình lại khi to đủ rồi thì sao? 00:06:34.665 --> 00:06:38.156 Ta có thể cho dòng này vào trong điều kiện 'if'. 00:06:38.983 --> 00:06:41.386 Dòng này đây, và chỉ chạy dòng này 00:06:41.386 --> 00:06:45.357 nếu currentWidth nhỏ hơn 1 giá trị nào đó, if the currentWidth is 00:06:45.357 --> 00:06:49.384 như là 300, thử xem nào. 00:06:54.373 --> 00:06:58.473 Thực ra không phải là currentWidth mà là newWidth mới được. 00:06:58.847 --> 00:07:01.656 Thử xem có dừng ở 300 không. 00:07:01.656 --> 00:07:05.626 Oh Noes ơi, to ra xem nào. 00:07:06.718 --> 00:07:08.771 Đẹp rồi. 00:07:09.555 --> 00:07:12.822 Kĩ thuật sử dụng requestAnimationFrame này 00:07:12.822 --> 00:07:15.247 hoàn toàn dùng được với Chrome, 00:07:15.247 --> 00:07:18.206 Firefox và IE10 trở lên. 00:07:18.265 --> 00:07:21.540 Còn có những thư viện JS 00:07:21.540 --> 00:07:25.464 để dùng requestAnimationFrame nếu được, 00:07:25.464 --> 00:07:29.584 và quay lai jdungf setInterval nếu là trình duyệt cũ. 00:07:30.467 --> 00:07:32.638 Đấy là một vấn đề của việc lập trình web: 00:07:32.638 --> 00:07:34.960 Mạng web thay đổi liên tục, 00:07:34.960 --> 00:07:36.725 các trình duyệt liên tục cung cấp các chức năng mới, 00:07:36.725 --> 00:07:40.022 lập trình viên cũng phát triển các kĩ thuật mới. 00:07:40.022 --> 00:07:43.505 Bạn cần liên tục học về những cái mới này 00:07:43.505 --> 00:00:00.000 thì sử dụng mới hiệu quả tối đa được.