+11

[JS tips] Các "chiêu trò" JS tưởng không hay mà hay không tưởng (phần 6)

Xin chào các bạn,

Theo tình hình cập nhật hiện tại, Covid vẫn đang quanh ta mà series JS tips của mình vẫn còn dài ra 😄 Và hôm nay mình lại tiếp tục chia sẻ với các bạn một số "trò hay" mà mình góp nhặt được. Bài viết được nằm trong series JSTips của mình, theo dõi series để có thể học hỏi hoặc đóng góp không chỉ kiến thức mà còn những lượt upvote nữa nhé:

[JS tips series] Các "chiêu trò" JS tưởng không hay mà hay không tưởng

Những thủ thuật trong kì này...mình cũng không biết phân loại ra sao. Cùng xem nào!

1. Phát hiện việc người dùng chuyển tab trên trình duyệt

Mở đầu với một "chiêu trò" khá là thú vị (với các bạn biết rồi thì không tính nhé 😄), nếu sử dụng JS lâu rồi mà chưa biết tới "trò" này (như mình) thì mình nghĩ là nên ngó qua một chút.

JS cho phép chúng ta phát hiện được rằng người dùng đang focus vào tab của chúng ta hay không, hoặc khi họ thu nhỏ cửa sổ trình duyệt xuống (minimize browser window). Việc này có tính ứng dụng khá cao như là dừng/phát nhạc khi người dùng không sử dụng/sử dụng tab. Hay là việc chạy quảng cáo đếm giây trước khi cho phép người dùng download chẳng hạn, dừng đếm giây khi người dùng chuyển qua tab khác, và tiếp tục đếm khi người dùng ở trang của chúng ta (bắt họ phải xem quảng cáo 😂 ).

Việc này được thực hiện khá là đơn giản như thế này thôi, pure JS luôn:

document.addEventListener('visibilitychange', function()
   document.title = document.visibilityState;
   console.log(document.visibilityState);
});

Và kết quả chúng ta nhận được sẽ rất là vi diệu như sau:

Bonus thêm một chút, ngoài cách trên kia mình lượm nhặt được thì cũng có nhiều cách khác nhau để các bạn check được điều này như là document.hidden chẳng hạn:

document.addEventListener('visibilitychange', function()
  console.log(document.hidden); // true or false
});

Kết quả thì cũng giống như bên trên:

2. Phát hiện kích thước trình duyệt

Tip thứ hai này vẫn là một tip "phát hiện", nói là phát hiện kích thước trình duyệt cho oai, chứ thực tế thì không hẳn như vậy đâu 😅. Thủ thuật này cũng rất là đơn giản, và sau khi nhìn đoạn code này các bạn sẽ hiểu được là tại sao không phát hiện được kích thước trình duyệt một cách chính xác:

const matchResult = window.matchMedia("(max-width: 767px)");
console.log(matchResult);

Thế đấy, nó chỉ trả ra kết quả với mỗi màn hình có kích thước max hoặc min mà ta định sẵn, cái này là media query như bên css đó. Và console sẽ cho ra kết quả như sau:

Cùng viết một hàm demo để thực hiện việc check nhé:

function isSmallScreen() {
   return window.matchMedia("(max-width: 767px)").matches;
}

3. Phát hiện light/dark mode của hệ điều hành

Trong thời gian gần đây, chế độ tối (dark mode) đã và đang được ưa chuộng bởi nhiều người dùng, nó gần như là một phần thiết yếu của một số người theo "chủ nghĩa bóng tối" - từ system dark mode, application dark mode, web dark mode, ... Vì vậy mà đã có không ít các trang web cũng sinh ra 2 giao diện là light mode và dark mode để phù hợp với xu thế.

Và đương nhiên là mặc định light/dark mode của web sẽ được hiển thị theo chế độ của OS hoặc là trình duyệt. Vì vậy nên thủ thuật này giúp bạn có thể phát hiện được chế độ sáng hoặc tối của hệ điều hành, giúp chúng ta hiển thị mặc định light/dark mode cho trang web của mình.

Cũng giống như thủ thuật trước, ở thủ thuật này cách phát hiện cũng tương tự, nhưng ta sẽ sử dụng prefers-color-scheme:

const matchResult = window.matchMedia("(prefers-color-scheme: dark)");
console.log(matchResult.matches);

Và khi viết thành một hàm thì kế quả thu được sẽ là:

4. Lấy phần mở rộng của file

Thủ thuật chỉ đơn giản là lấy phần mở rộng của một file mà chúng ta đã biết tên của file đó. Giả sử ta có file demo.txt thì phần mở rộng sẽ là txt.

var file1 = "50.xsl";
var file2 = "30.doc";
getFileExtension(file1); //returs xsl
getFileExtension(file2); //returs doc

function getFileExtension(filename) {
  /*TODO*/
}

Rất đơn giản phải không? Nhưng ở thủ thuật cuối cùng này chúng ta sẽ có một phép so sánh giữa các cách làm mà mình sắp liệt kê ra sau đây nhé.

4.1 Sử dụng regex

Regex là một thứ...khá là lằng nhằng cho dù có là ngôn ngữ lập trình phổ biến nào đi nữa và trong phần này cũng vậy:

function getFileExtension1(filename) {
  return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename)[0] : undefined;
}

Kết quả khi sử dụng cách này với một vài lần test như sau:

4.2 Sử dụng phương thức split

Cách này là cách mà hầu như chúng ta sẽ nghĩ tới khi được hỏi bài toán này, chỉ đơn giản là sử dụng phương thức split() có sẵn và lấy ra phần tử cuối cùng của mảng thu được mà thôi:

function getFileExtension2(filename) {
  return filename.split('.').pop();
}

Nhưng có vẻ nó cũng không chạy chính xác hoàn toàn với một số trường hợp

4.3 Sử dụng phương thức slice, lastIndexOf

Khuyết điểm của 2 solution bên trên sẽ được khắc phục bằng cách sử dụng slice()lastIndexOf() cộng thêm một chút trick như sau:

function getFileExtension3(filename) {
  return filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
}

console.log(getFileExtension3(''));                            // ''
console.log(getFileExtension3('filename'));                    // ''
console.log(getFileExtension3('filename.txt'));                // 'txt'
console.log(getFileExtension3('.hiddenfile'));                 // ''
console.log(getFileExtension3('filename.with.many.dots.ext')); // 'ext'

Mọi thứ ổn hơn rồi phải không! Nhưng mà hàm này nó đã làm gì?

  • Phương thức String.lastIndexOf(".") sẽ trả ra vị trí cuối cùng mà dấu "." xuất hiện, nếu không có thì nó sẽ trả ra -1. Cái này thì bạn nào cũng biết đúng không!?
  • Trong trường hợp tên file là 'filename''.hiddenfile' thì String.lastIndexOf(".") sẽ trả ra lần lượt tương ứng là -1 và 0, vậy nên là (filename.lastIndexOf(".") - 1 trong 2 trường hợp này sẽ cho ra -2 và -1. Toán tử shift >>> sẽ chuyển -1 thành 4294967295 và -2 thành 4294967294. Để ý kĩ nhé, đây chính là "một chút trick" mà mình nhắc tới bên trên đó.
  • Sau đó phương thức String.prototype.slice() sẽ lấy ra được phần mở rộng của file dựa vào chỉ số mà ta tính toán được ở trên. Nếu như chỉ số mà vượt quá độ dài của chuỗi thì nó sẽ trả ra chuỗi rỗng ""

4.4 So sánh

Mình có thực hiện test một vài cách để so sánh xem chúng chạy ra sao, thì kết quả thu được như sau (test trên Chrome 81.0.4044 / Windows 10 version 1909 build 18363.778):

Kết luận

Khép lại bài lần này với 3 thủ thuật chuyên về việc "phát hiện" 😄 và một thủ thuật cuối để lấy phần mở rộng của file. Mình hy vọng các thủ thuật này mang lại phần nào sự hứng thú cũng như bổ ích cho các bạn. Cảm ơn các bạn đã chịu khó đọc tới cuối bài, hẹn gặp lại vào các bài viết sau.

Xin cảm ơn!

Reference:


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.