Cập nhật giá trị cookie, phát hiện hiệu ứng di chuột và hơn thế nữa

Cover created by Author
Cover created by Author

 

Vì JavaScript là một trong những ngôn ngữ phổ biến nhất, nên có rất nhiều thư viện trên mạng. Điều đó không có nghĩa là chúng ta nên bị ám ảnh bởi việc liên tục thêm nhiều hơn nữa vào cơ sở mã của mình. Chúng ta có thể chỉ cần một tiện ích này mà chúng ta có thể tự xây dựng.

Khoảng 5 năm trước, việc xóa bỏ mô-đun npm phổ biến left-pad đã mang đến sự hỗn loạn nhất thời cho Internet. Đó là một tiện ích có thể dễ dàng được xây dựng trong một dòng. Trên thực tế, nó có sẵn trong thông số kỹ thuật của ES7.

Làm thế nào chúng ta có thể ngăn điều đó xảy ra? Chúng ta có nên liên tục phát minh lại nó không?

Không, chúng ta cần phải khôn ngoan và ngăn nắp với các phụ thuộc npm của mình. Chúng ta cần đánh giá xem có đáng để thêm lib cho chỉ một tiện ích hay không. Việc tự mã hóa nó sẽ giúp chúng ta kiểm soát nhiều hơn và hiểu rõ hơn về những gì đang được thực thi.

Trong bài viết này, chúng ta sẽ thấy một ví dụ về mười tiện ích một lớp JavaScript mạnh mẽ, dễ xây dựng và thử nghiệm.

1. Tạo Boolean Ngẫu nhiên

Chúng ta biết rằng Math.random trả về một giá trị từ 0 đến 1. Chúng ta có thể sử dụng kiến ​​thức đó để tạo một trình tạo boolean rất đơn giản.

const randomBoolean = () => Math.random() >= 0.5;

// ✅ res will be true or false
const res = randomBoolean();

2. Tạo một số ngẫu nhiên

Chúng ta sẽ tận dụng API Math.random một lần nữa. Bằng cách nhân kết quả với số tối đa của chúng ta và làm tròn nó. Sau đó, chúng ta sẽ nhận được một số từ 0 đến max.

const randomNumber = (max) => Math.round(Math.random() * max);

// ✅ res is a number between 0 and 10
const res = randomNumber(10);

Thật đơn giản để mở rộng phương pháp này hơn nữa để chấp nhận phạm vi tối thiểu và tối đa.

const randomNumber = (min, max) => Math.round(Math.random() * (max - min) + min);

// ✅ res is a number between 5 and 10
const res = randomNumber(5, 10);

Những gì chúng ta đang làm trong đoạn mã trên là tạo ra một số giữa sự khác biệt về khoảng thời gian. Sau đó, chúng ta đang thêm giá trị min. Điều đó sẽ tạo ra một số trong phạm vi đã cho của chúng tôi.

3. Tạo ID ngẫu nhiên

Để tạo tiện ích này, chúng ta sẽ dựa vào phương thức toString. Nó sẽ cho phép chúng ta chuyển đổi các số ngẫu nhiên của chúng ta thành chuỗi.

num.toString(radix)

Lưu ý rằng phương thức này nhận một tham số tùy chọn radixphải nằm trong khoảng từ 2 đến 36.

Đối với phương pháp này, chúng ta sẽ sử dụng giá trị cơ bản tối đa được chấp nhận 36 và đây là lý do:

“Base36 là một lược đồ mã hóa nhị phân thành văn bản đại diện cho dữ liệu nhị phân ở định dạng chuỗi ASCII bằng cách dịch nó thành biểu diễn cơ số 36. Lựa chọn số 36 thuận tiện ở chỗ các chữ số có thể được biểu diễn bằng chữ số Ả Rập 0-9 và các chữ cái Latinh A – Z [1] ”- Wikipedia

Chúng ta sẽ bỏ qua hai ký tự đầu tiên vì chúng rất có thể sẽ là 0 .. Hãy xem mã của chúng ta với một trường hợp ở góc:

const randomId = () => Math.random().toString(36).substring(2);

// ❌ if Math.ranodm is 0 a will res will be ""
const res = randomId();

⚠️ Kết quả Math.random loại trừ 1 và bao gồm 0. Điều đó có nghĩa là có một khả năng nhỏ là kết quả randomId của chúng ta là ''". Đó là bởi vì chúng ta đang dựa vào số bắt đầu của dãy là 0.

Chúng ta chỉ cần trả về 0 cho trường hợp đó hoặc bất kỳ id chuỗi mặc định nào khác mà bạn thấy phù hợp:

const randomId = () => Math.random().toString(36).substring(2) || '0';

// ✅ res will be '0' when Math.random() is 0
const res = randomId();

Phương pháp randomId của chúng ta hiện đã rất mạnh mẽ. Nó sẽ trả về một id ngẫu nhiên gồm cả chữ và số.

4. Tạo một số Hex ngẫu nhiên

Chúng ta có thể áp dụng các nguyên tắc tương tự mà chúng ta đã thấy ở trên để tạo một hàm số hex ngẫu nhiên. Đối với phương pháp tiếp theo, chúng ta sẽ sử dụng hàm đệm chuỗi ES7: padEnd.

const randomHex = () => `#${Math.random().toString(16).slice(2,9).padEnd(6,'0')}`;

// ✅ res is now a hex value like #c3fd5db
const res = randomHex();

Nếu không muốn dựa vào ES7, chúng ta có thể đơn giản làm theo cách hiệu quả hơn:

const randomHex = () => `#${(0x1000000 + Math.random() * 0xffffff).toString(16).slice(1, 7)}`;

// ✅ res is now a hex value like #c3fd5db
const res = randomHex();

Cả hai giải pháp đều tuyệt vời. Lựa chọn của bạn sẽ phụ thuộc nếu bạn muốn đánh đổi một chút hiệu suất để có thể đọc được.

5. Khởi tạo một mảng

Chúng ta liên tục thao tác với các mảng. Rất may, với tất cả các thông số kỹ thuật ECMAScript mới, chúng ta có nhiều công cụ mảng hơn. Chúng ta có thể tạo một lớp lót tuyệt vời với nó.

Array(x) là một cách tuyệt vời để khởi tạo một mảng có độ dài x. Hãy sử dụng nó để tạo một mảng số được sắp xếp.

const generateSortedNumberArray = (length) => [...Array(length).keys()]

// ✅ res is [ 0, 1, 2, 3, 4 ]
const res = generateSortedNumberArray(5);

Chúng ta có thể dễ dàng tạo một mảng boolean:

const booleanArray = (length, value = false) => Array(length).fill(value);

// ✅ res1 is [ false, false ]
const res1 = booleanArray(2);

// ✅ res2 is [ true, true ]
const rest2 = booleanArray(2, true);

Theo mặc định, nó sẽ là false, nhưng chúng ta có thể ghi đè nó bằng cách truyền đối số thứ hai vào hàm.

6. Loại bỏ các bản sao khỏi một mảng

Loại bỏ các bản sao của một mảng là một việc dễ dàng thực hiện. Chúng ta có thể sử dụng đối tượng Set cho điều đó và sau đó chuyển đổi trở lại một mảng.

const removeDuplicates = (target) => [...new Set(target)];

// ✅ res is [ 1, 2, 3, 4 ]
const res = removeDuplicates([1, 2, 2, 3, 4, 1

7. Trộn một mảng

Việc xáo trộn một mảng thoạt nghe có vẻ hơi khó khăn. Chúng ta có thể sử dụng phương pháp sort cho điều đó.

⚠️ Lưu ý rằng phương thức sort sẽ thay đổi mảng đích. Trước tiên, chúng ta sẽ phải tạo một bản sao cho mảng của mình và sau đó sắp xếp nó. Đây là mã:

const shuffleArray = (target) => [...target].sort(() => Math.random() - 0.5);

const target = [ 1, 2, 3, 4];

// ✅ res1 is now a shuffled array version of target
const res1 = shuffleArray(target);

// ✅ the utility works with any kind of array values
const res2 = shuffleArray([ 'one', 'two', 'three', 'four' ]);

API phương thức sort lấy các đối số hai mục để so sánh giữa các đối tượng với nhau. Chúng ta sẽ bỏ qua những điều đó khi chúng ta quyết định ngẫu nhiên nếu một mặt hàng lớn hơn đơn đặt hàng.

8. Phát hiện Tính năng Hiệu ứng Di chuột

Vì lý do trải nghiệm người dùng nên biết người dùng có thiết bị có khả năng hiệu ứng di chuột hay không sẽ rất hữu ích. Chúng ta có thể muốn điều chỉnh bố cục của mình tùy thuộc vào tiêu chí đó.

API matchMedia sẽ cho phép chúng ta tạo ra một tiện ích cho việc đó:

const hasOverEffect = () => window.matchMedia('(any-hover: hover)').matches;

// ✅ res will be true for desktop devices and false for mobile ones
const res = hasOverEffect();

Bằng cách truy vấn matchMedia, chúng ta có thể kiểm tra xem trình duyệt có vượt quá khả năng hay không.

9. Nhận giá trị cookie

Đôi khi chúng ta dựa vào các thư viện của bên thứ ba như cookie-manager hoặc js-cookies để xử lý tất cả các tương tác với cookie. Nếu chúng ta chỉ cần một vài tiện ích cookie, chúng ta có thể tự triển khai chúng.

Dễ dàng truy cập cookie phía máy khách từ JavaScript:

"Cookie  có thuộc tính document cho phép bạn đọc và ghi các cookie được liên kết với tài liệu. Nó đóng vai trò như một getter và setter cho các giá trị thực của cookie" - MDN

Tóm lại, tất cả những gì liên quan đến cookie của trình duyệt là xử lý chuỗi document.cookie chứa tất cả thông tin.

Hãy tạo một tiện ích để nhận giá trị của một cookie nhất định theo tên của nó.

const getCookieValue = (name) => document.cookie.match(new RegExp(`${name}=(.*?);`))?.[1];

// ✅ res is the the value of the cookie feature_x
const res = getCookieValue('feature_x');

Lưu ý rằng chúng ta sẽ dựa vào một biểu thức chính quy để tìm ra giá trị. Chúng ta sẽ sử dụng các nhóm regex cho nó bằng cách sử dụng dấu ngoặc đơn. Chúng ta sẽ sử dụng toán tử tùy chọn ? Để ngăn chặn bất kỳ lỗi không xác định nào.

⚠️ Như đã đề cập trước đây, bạn sẽ không thể truy cập cookie Http Only từ phía JavaScript.

10. Cập nhật giá trị cookie

Cập nhật giá trị cookie có vẻ là một nhiệm vụ nhỏ. Tuy nhiên, bảo mật trình duyệt làm cho nó khó khăn.

API document.cookie chỉ tiết lộ giá trị của cookie. Nó bỏ qua bất kỳ domain hoặc thông tin path nào về cookie. Để cập nhật một cookie, bạn sẽ cần hai phần thông tin đó. Nếu không, bạn có thể tạo một cookie mới thay vì cập nhật cookie hiện có.

const setCookieValue = (name, value, path, domain) =>
    document.cookie = `${name}=${value};${path ? 'path=' + path + '; ' : ''}${domain ? 'domain='+ domain + '; ' : ''}`
    
// ✅ updates the value of the cookie named feature_x
setCookieValue('feature_x', true);

Lưu ý cách document.cookie là cả giao diện đọc và ghi của API cookie.

Tổng kết 

Chúng ta đã thấy việc tạo các tiện ích cho cơ sở mã JavaScript của chúng ta dễ dàng và thú vị như thế nào. Bằng cách xây dựng các chức năng của riêng mình, chúng ta sẽ giành được quyền kiểm soát những gì đang chạy trong các ứng dụng của chúng tôi. Một điểm chuyên nghiệp khác là chúng ta sẽ tìm hiểu thêm thông tin chi tiết về web và trình duyệt thay vì dựa vào các libs để thực hiện công việc cho chúng tôi.

Vanilla JavaScript ngày càng trở nên mạnh mẽ hơn với mỗi lần phát hành EMAScript. Điều đó có nghĩa là chúng ta sẽ cần ít thư viện hơn. Chúng ta sẽ có những công cụ tốt hơn để xây dựng nhiều tiện ích hơn.

Như với bất kỳ mã nào, chúng ta chỉ phải theo dõi bộ chuyển đổi và polyfills để ứng dụng của chúng ta có thể chạy trong bất kỳ trình duyệt nào.

Bài viết gốc tại đây.

Hiện tại khóa học Web Frontend tại Techmaster Vietnam vẫn liên tục tuyển sinh các lớp tiếp theo. Và trong tình hình dịch bệnh phức tạp, lớp sẽ chuyển sang học hình thức trực tuyến có tương tác, thời lượng và chất lượng không đổi, vẫn đảm bảo việc làm cho học viên tốt nghiệp.

Chi tiết khóa học: https://frontend.techmaster.vn/.

Liên hệ tư vấn: Mr Thịnh - 0987273764 (zalo).