auxclick sắp có trên Chrome 55

Khi nào một lượt nhấp không phải là click? Đối với một nhà phát triển web đang làm việc trên một giao diện người dùng phức tạp, đó không phải là một câu hỏi triết học trừu tượng. Nếu bạn đang triển khai hành vi nhập bằng chuột tuỳ chỉnh, điều quan trọng là phải lưu ý đến ý định của người dùng. Ví dụ: nếu người dùng nhấp vào một đường liên kết bằng nút giữa của chuột, thì bạn có thể giả định rằng họ muốn mở một thẻ mới có nội dung của đường liên kết đó. Nếu người dùng nhấp chuột giữa vào một phần tử giao diện người dùng ngẫu nhiên, thì bạn có thể giả định rằng đó là do vô tình và bỏ qua dữ liệu đầu vào đó, trong khi một lượt nhấp vào nút chính sẽ kích hoạt phản hồi từ giao diện người dùng.

Bạn có thể lập mô hình các lượt tương tác tinh tế này thông qua một trình nghe sự kiện click duy nhất, mặc dù hơi cồng kềnh. Bạn sẽ phải kiểm tra rõ ràng thuộc tính button của MouseEvent để xem thuộc tính này có được đặt thành 0, đại diện cho nút chính hay không, so với mọi thuộc tính khác, trong đó 1 thường đại diện cho nút giữa, v.v. Tuy nhiên, không nhiều nhà phát triển kiểm tra rõ ràng thuộc tính button, dẫn đến mã xử lý tất cả click giống nhau, bất kể nút nào được nhấn.

Kể từ Chrome 55, một loại MouseEvent mới có tên là auxclick sẽ được kích hoạt để phản hồi mọi lượt nhấp được thực hiện bằng nút không phải chính. Cùng với sự kiện mới này là một thay đổi tương ứng trong hành vi của sự kiện click: sự kiện này sẽ chỉ kích hoạt khi người dùng nhấn nút chuột chính. Chúng tôi hy vọng những thay đổi này sẽ giúp nhà phát triển web dễ dàng viết trình xử lý sự kiện chỉ phản hồi loại lượt nhấp mà họ quan tâm mà không cần phải kiểm tra cụ thể thuộc tính MouseEvent.button.

Giảm kết quả dương tính giả

Như đã đề cập, một động lực để tạo auxclick là tránh triển khai trình xử lý click tuỳ chỉnh ghi đè nhầm hành vi "nhấp chuột giữa-mở thẻ". Ví dụ: giả sử bạn đã viết một trình xử lý sự kiện click sử dụng History API để ghi lại thanh vị trí và triển khai các thao tác điều hướng trang đơn tuỳ chỉnh. Mã này có thể có dạng như sau:

document.querySelector('#my-link').addEventListener('click', event => {
    event.preventDefault();
    // ...call history.pushState(), use client-side rendering, etc....
});

Logic tuỳ chỉnh của bạn có thể hoạt động như dự kiến khi được kích hoạt bằng nút chính của chuột, nhưng nếu mã đó chạy khi người dùng nhấp vào nút giữa, thì đó sẽ là một kết quả dương tính giả hiệu quả. Trước hành vi mới, bạn sẽ ngăn hành động mặc định là mở một thẻ mới, điều này trái với kỳ vọng của người dùng. Mặc dù bạn có thể kiểm tra rõ ràng event.button === 0 ở đầu trình xử lý và chỉ thực thi mã nếu trường hợp đó xảy ra, nhưng bạn dễ quên hoặc không bao giờ nhận ra việc cần làm đó.

Chỉ chạy mã bạn cần

Mặt trái của việc ít có kết quả dương tính giả hơn là lệnh gọi lại auxclick sẽ chỉ chạy khi thực sự có một nút chuột không phải là nút chính được nhấp vào. Ví dụ: nếu có mã cần tính toán URL đích thích hợp trước khi mở một thẻ mới, bạn có thể theo dõi auxclick và đưa logic đó vào lệnh gọi lại. Phương thức này sẽ không phát sinh chi phí khi chạy khi nhấp vào nút chuột chính.

Khả năng tương thích và hỗ trợ trình duyệt

Hành vi mới này hiện chỉ được triển khai trong Chrome 55. Như đã đề cập trong đề xuất ban đầu, chúng tôi rất mong nhận được ý kiến phản hồi (cả tích cực và tiêu cực) từ cộng đồng nhà phát triển web. Việc gửi vấn đề trên GitHub là cách tốt nhất để chia sẻ ý kiến phản hồi đó với những người đang làm việc trong quy trình chuẩn hoá.

Trong thời gian chờ đợi, nhà phát triển không phải đợi auxclick được cung cấp rộng rãi để làm theo một số phương pháp hay nhất để xử lý các sự kiện chuột. Nếu dành thời gian kiểm tra giá trị của thuộc tính MouseEvent.button ở đầu trình xử lý sự kiện click, bạn có thể đảm bảo rằng mình sẽ thực hiện hành động thích hợp. Mẫu sau đây sẽ xử lý các lượt nhấp chính và phụ theo cách khác nhau, cho dù có hỗ trợ gốc cho auxclick hay không:

function handlePrimaryClick(event) {
    // ...code to handle the primary button click...
}

function handleAuxClick(event) {
    // ...code to handle the auxiliary button click….
}

document.querySelector('#my-link').addEventListener('click', event => {
    if (event.button === 0) {
    return handlePrimaryClick(event);
    }


    // This provides fallback behavior in browsers without auxclick.
    return handleAuxClick(event);
});

// Explicitly listen for auxclick in browsers that support it.
document.querySelector('#my-link').addEventListener('auxclick', handleAuxClick);