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