Sau khi xem xét cẩn thận, tôi đề xuất đây là một giải pháp sạch hơn trong chủ đề này:
$("input").focus(function(){
$(this).on("click.a keyup.a", function(e){
$(this).off("click.a keyup.a").select();
});
});
Vấn đề:
Dưới đây là một chút giải thích:
Trước tiên, hãy xem thứ tự các sự kiện khi bạn di chuột hoặc tab vào một trường.
Chúng tôi có thể đăng nhập tất cả các sự kiện có liên quan như thế này:
$("input").on("mousedown focus mouseup click blur keydown keypress keyup change",
function(e) { console.log(e.type); });
Lưu ý : Tôi đã thay đổi giải pháp này để sử dụng click
thay mouseup
vì nó xảy ra sau đó trong đường ống sự kiện và dường như gây ra một số vấn đề trong firefox theo nhận xét của @ Jocie
Một số trình duyệt cố gắng định vị con trỏ trong mouseup
hoặc click
sự kiện. Điều này có ý nghĩa vì bạn có thể muốn bắt đầu dấu mũ ở một vị trí và kéo qua để tô sáng một số văn bản. Nó không thể chỉ định vị trí dấu mũ cho đến khi bạn thực sự nhấc chuột. Vì vậy, các chức năng xử lý focus
được định mệnh phản hồi quá sớm, khiến trình duyệt ghi đè lên vị trí của bạn.
Nhưng điều khó khăn là chúng tôi thực sự muốn xử lý sự kiện tập trung. Nó cho chúng tôi biết lần đầu tiên có người vào trường. Sau thời điểm đó, chúng tôi không muốn tiếp tục ghi đè hành vi lựa chọn của người dùng.
Giải pháp:
Thay vào đó, trong focus
trình xử lý sự kiện, chúng ta có thể nhanh chóng đính kèm người nghe cho các sự kiện click
(nhấp vào) và keyup
(tab trong) sắp diễn ra.
Lưu ý : Keyup của một sự kiện tab sẽ thực sự kích hoạt trong trường đầu vào mới, không phải trường hợp trước đó
Chúng tôi chỉ muốn bắn sự kiện một lần. Chúng tôi có thể sử dụng .one("click keyup)
, nhưng điều này sẽ gọi trình xử lý sự kiện một lần cho mỗi loại sự kiện . Thay vào đó, ngay khi nhấn chuột hoặc gõ phím, chúng tôi sẽ gọi chức năng của chúng tôi. Điều đầu tiên chúng ta sẽ làm là loại bỏ các trình xử lý cho cả hai. Bằng cách đó, sẽ không có vấn đề gì cho dù chúng tôi đã gắn thẻ hoặc kết nối. Hàm sẽ thực thi chính xác một lần.
Lưu ý : Hầu hết các trình duyệt tự nhiên chọn tất cả văn bản trong một sự kiện tab, nhưng như hoạt hình đã chỉ ra , chúng tôi vẫn muốn xử lý keyup
sự kiện, nếu không mouseup
sự kiện sẽ vẫn còn tồn tại bất cứ lúc nào chúng tôi đã đăng nhập. Chúng tôi lắng nghe cả hai để chúng tôi có thể bật tắt người nghe ngay khi chúng tôi xử lý lựa chọn.
Bây giờ, chúng tôi có thể gọi select()
sau khi trình duyệt đã chọn, vì vậy chúng tôi chắc chắn sẽ ghi đè hành vi mặc định.
Cuối cùng, để bảo vệ thêm, chúng ta có thể thêm các không gian tên sự kiện vào các hàm mouseup
và các keyup
hàm để .off()
phương thức không loại bỏ bất kỳ trình nghe nào khác có thể đang phát.
Đã thử nghiệm trong IE 10+, FF 28+ và Chrome 35+
Ngoài ra, nếu bạn muốn mở rộng jQuery với một hàm được gọi once
sẽ chạy chính xác một lần cho bất kỳ số lượng sự kiện nào :
$.fn.once = function (events, callback) {
return this.each(function () {
var myCallback = function (e) {
callback.call(this, e);
$(this).off(events, myCallback);
};
$(this).on(events, myCallback);
});
};
Sau đó, bạn có thể đơn giản hóa mã hơn nữa như thế này:
$("input").focus(function(){
$(this).once("click keyup", function(e){
$(this).select();
});
});