1 00:00:00,821 --> 00:00:03,421 Ta lại quay lại về cái đếm ngược Oh Noes. 2 00:00:03,979 --> 00:00:07,242 Giờ nếu ta muốn ảnh của Oh Noes to dần ra 3 00:00:07,242 --> 00:00:09,587 khi đếm ngược dần về 0, 4 00:00:09,587 --> 00:00:12,267 thì phải làm thế nào? 5 00:00:12,860 --> 00:00:15,287 Một cách làm là tạo ảnh động 6 00:00:15,287 --> 00:00:19,140 với CSS của ảnh này với window.setInterval. 7 00:00:20,663 --> 00:00:22,937 Bước đầu tiên, tôi sẽ tìm ảnh này 8 00:00:22,937 --> 00:00:25,142 và gán nó vào một biến. 9 00:00:25,167 --> 00:00:30,167 ohnoes = document.getElemenyById("ohnoes"); 10 00:00:32,144 --> 00:00:34,443 Ta đặt style khởi điểm, 11 00:00:34,443 --> 00:00:36,787 tức là sẽ bắt đầu từ chiều rộng này. 12 00:00:36,787 --> 00:00:39,178 Rồi ảnh sẽ lớn dần ra từ đó. 13 00:00:39,899 --> 00:00:44,263 Giờ ta viết một hàm makeItBigger 14 00:00:44,543 --> 00:00:47,641 để làm ảnh to ra từng chút một. 15 00:00:48,386 --> 00:00:52,738 Ở đây ta lấy giá trị style.width, 16 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. 17 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. 18 00:01:04,604 --> 00:01:07,621 window.setInterval(makeItBigger), 19 00:01:07,623 --> 00:01:09,701 Ta muốn nó to lên từng nào nào? 20 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? 21 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, 22 00:01:13,881 --> 00:01:15,378 thì tức là sẽ cần thay đổi trong khoảng tần suất 23 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. 24 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. 25 00:01:25,664 --> 00:01:28,343 Không được rồi. 26 00:01:29,007 --> 00:01:31,422 Bạn biết tại sao không? Hơi rắc rối đấy. 27 00:01:31,422 --> 00:01:33,963 Ta sẽ xem lại xem nào. 28 00:01:34,138 --> 00:01:39,074 Giá trị của ohnoes.style.width 29 00:01:39,074 --> 00:01:41,138 sau khi chạy dòng lệnh này là bao nhiêu nào? 30 00:01:41,674 --> 00:01:45,717 Chắc là 50px rồi sẽ đến 51px rồi, 31 00:01:45,717 --> 00:01:50,187 nhưng ta cứ log ra xem ohnoes.style.width là bao nhiêu. 32 00:01:50,187 --> 00:01:52,798 Ta đặt cái này vào trong infoDiv. 33 00:01:52,997 --> 00:01:56,304 Nó sẽ bằng... 34 00:01:58,522 --> 00:02:00,786 50px, okay. 35 00:02:00,786 --> 00:02:05,162 Rồi khi ta cộng thêm 1 vào 50px, 36 00:02:05,744 --> 00:02:07,903 50px thêm 1 là gì? 37 00:02:07,903 --> 00:02:11,398 Bạn đoán là 51px, nhưng JS 38 00:02:11,398 --> 00:02:15,366 coi 50px là 1 string, 39 00:02:16,365 --> 00:02:20,400 nên thêm 1 sẽ thành 50px1, 40 00:02:20,400 --> 00:02:22,635 tức là chả có ý nghĩa gì. 41 00:02:22,635 --> 00:02:25,955 Như vậy là trình duyệt sẽ không 42 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. 43 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 44 00:02:33,576 --> 00:02:35,957 về kiểu số, 45 00:02:35,957 --> 00:02:37,743 rồi cộng 1 vào số đó, 46 00:02:37,743 --> 00:02:40,400 rồi lại thêm "px" vào sau. 47 00:02:40,984 --> 00:02:45,323 Ta có thể đặt cái này vào trong parseFloat, 48 00:02:45,836 --> 00:02:47,565 thế là đổi được về dạng số. 49 00:02:47,565 --> 00:02:50,094 Rồi ta đóng ngoặc cụm này lại, 50 00:02:50,260 --> 00:02:53,081 và thêm "px" vào sau. 51 00:02:53,081 --> 00:02:56,122 Được rồi. Ảnh đang to dần lên rồi. 52 00:02:57,952 --> 00:02:59,570 Bạn thấy cái lằng nhằng 53 00:02:59,570 --> 00:03:01,451 trong việc tạo hình động với CSS 54 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 55 00:03:03,808 --> 00:03:06,199 chuyển bỏ đơn vị đó đi... trời ơi ảnh to quá... 56 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. 57 00:03:12,726 --> 00:03:14,694 Ảnh này to ra quá rồi. 58 00:03:14,694 --> 00:03:17,086 Còn một vài vấn đề thường gặp 59 00:03:17,086 --> 00:03:20,787 khi sử dụng setInterval để thay đổi thuộc tính CSS. 60 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 61 00:03:24,249 --> 00:03:28,043 đợi đúng theo số interval này. 62 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, 63 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, 64 00:03:35,892 --> 00:03:38,411 thì hoạt hình động trông sẽ không được mượt. 65 00:03:39,132 --> 00:03:41,571 Thứ 2 nữa là trình duyệt sẽ gọi hàm này 66 00:03:41,571 --> 00:03:43,486 kể cả khi tab này ẩn đi, 67 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. 68 00:03:48,409 --> 00:03:50,312 Vì vậy nên là các trình duyệt hiện đại 69 00:03:50,312 --> 00:03:52,065 có một hàm mới, 70 00:03:52,065 --> 00:03:55,630 chuyên dùng để tạo hoạt hình với DOM, 71 00:03:55,630 --> 00:03:58,832 gọi là window.requestAnimationFrame. 72 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 73 00:04:02,886 --> 00:04:07,886 và gọi hàm requestAnimationFrame() 74 00:04:09,166 --> 00:04:11,731 ở trong hàm này. 75 00:04:11,731 --> 00:04:15,026 Và ta sẽ chỉ nó đến 76 00:04:15,026 --> 00:04:18,243 hàm makeItBigger. 77 00:04:19,173 --> 00:04:24,118 Rồi sẽ sẽ gọi hàm makeItBigger() ngay khi tải trang web. 78 00:04:27,588 --> 00:04:30,690 Oh! Ảnh này đang to lên nahnh quá. 79 00:04:30,690 --> 00:04:34,672 Trình duyệt đang gọi hàm makeItBigger liên tục 80 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, 81 00:04:37,829 --> 00:04:39,943 tức là gấp đôi tần số vừa rồi. 82 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, 83 00:04:43,112 --> 00:04:45,271 tính toán ra thì 84 00:04:45,271 --> 00:04:48,078 là cộng thêm 60px mỗi giây. 85 00:04:48,078 --> 00:04:50,832 Chỉ vài giây là ảnh đã to hơn cả trang rồi. 86 00:04:50,832 --> 00:04:52,771 Giờ to quá đi mất rồi. 87 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? 88 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 89 00:04:58,541 --> 00:05:01,316 là kiểm tra xem đã chạy bao nhiêu giây rồi, 90 00:05:01,316 --> 00:05:03,474 rồi tính giá trị của chiều rộng 91 00:05:03,474 --> 00:05:05,170 dựa theo giá trị đó. 92 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, 93 00:05:09,036 --> 00:05:11,033 trước khi hàm này được gọi. 94 00:05:11,033 --> 00:05:14,632 var startTime... ảnh lại to ra nữa rồi. 95 00:05:14,632 --> 00:05:17,407 new Date().getTime(); 96 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. 97 00:05:20,866 --> 00:05:25,866 var currTime = new Date().getTime(); 98 00:05:27,007 --> 00:05:28,691 Giờ ta phải tính, 99 00:05:28,691 --> 00:05:31,652 ví dụ nếu muốn ảnh to ra 30px/s, 100 00:05:31,652 --> 00:05:34,457 và bắt đầu từ 50px, 101 00:05:34,457 --> 00:05:37,176 ta tính toán ở đây. 102 00:05:37,630 --> 00:05:42,630 newWidth bằng 50 + ..., 50 là giá trị khởi điểm... 103 00:05:44,452 --> 00:05:49,028 cộng thêm currentTime trừ đi startTime. 104 00:05:49,028 --> 00:05:50,586 Giá trị này là millisecond, nên ta sẽ 105 00:05:50,586 --> 00:05:53,174 chia cho 1000, 106 00:05:53,174 --> 00:05:57,464 rồi nhân với 30, 107 00:05:57,464 --> 00:06:00,058 bỏi vì ta muốn tăng lên 30px mỗi giây. 108 00:06:00,280 --> 00:06:02,300 Đây là newWidth rồi. 109 00:06:02,300 --> 00:06:07,300 Giờ ta sẽ đặt style.width cho bằng newWidth. 110 00:06:10,261 --> 00:06:13,976 newWidth... đây được rồi, 111 00:06:13,976 --> 00:06:18,976 thế này là được 30px/s thật mượt rồi. 112 00:06:19,967 --> 00:06:23,983 Ta có thể thay đổi số này nếu muốn nó chạy 113 00:06:23,983 --> 00:06:28,625 nhanh hơn chậm hơn. 114 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? 115 00:06:34,665 --> 00:06:38,156 Ta có thể cho dòng này vào trong điều kiện 'if'. 116 00:06:38,983 --> 00:06:41,386 Dòng này đây, và chỉ chạy dòng này 117 00:06:41,386 --> 00:06:45,357 nếu currentWidth nhỏ hơn 1 giá trị nào đó, if the currentWidth is 118 00:06:45,357 --> 00:06:49,384 như là 300, thử xem nào. 119 00:06:54,373 --> 00:06:58,473 Thực ra không phải là currentWidth mà là newWidth mới được. 120 00:06:58,847 --> 00:07:01,656 Thử xem có dừng ở 300 không. 121 00:07:01,656 --> 00:07:05,626 Oh Noes ơi, to ra xem nào. 122 00:07:06,718 --> 00:07:08,771 Đẹp rồi. 123 00:07:09,555 --> 00:07:12,822 Kĩ thuật sử dụng requestAnimationFrame này 124 00:07:12,822 --> 00:07:15,247 hoàn toàn dùng được với Chrome, 125 00:07:15,247 --> 00:07:18,206 Firefox và IE10 trở lên. 126 00:07:18,265 --> 00:07:21,540 Còn có những thư viện JS 127 00:07:21,540 --> 00:07:25,464 để dùng requestAnimationFrame nếu được, 128 00:07:25,464 --> 00:07:29,584 và quay lai jdungf setInterval nếu là trình duyệt cũ. 129 00:07:30,467 --> 00:07:32,638 Đấy là một vấn đề của việc lập trình web: 130 00:07:32,638 --> 00:07:34,960 Mạng web thay đổi liên tục, 131 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, 132 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. 133 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 134 00:07:43,505 --> 00:00:00,000 thì sử dụng mới hiệu quả tối đa được.