หลังจากตรวจสอบอย่างรอบคอบฉันเสนอสิ่งนี้เป็นวิธีแก้ปัญหาไกลสะอาดภายในหัวข้อนี้
$("input").focus(function(){
$(this).on("click.a keyup.a", function(e){
$(this).off("click.a keyup.a").select();
});
});
ปัญหา:
นี่คือคำอธิบายเล็กน้อย:
ก่อนอื่นมาดูลำดับเหตุการณ์เมื่อคุณวางเมาส์หรือแท็บลงในช่อง
เราสามารถบันทึกกิจกรรมที่เกี่ยวข้องทั้งหมดดังนี้:
$("input").on("mousedown focus mouseup click blur keydown keypress keyup change",
function(e) { console.log(e.type); });
หมายเหตุ : ฉันได้เปลี่ยนวิธีแก้ปัญหานี้เพื่อใช้งานclick
มากกว่าmouseup
ที่จะเกิดขึ้นในภายหลังในท่อส่งเหตุการณ์และดูเหมือนว่าจะก่อให้เกิดปัญหาบางอย่างใน firefox ตามความคิดเห็นของ @ Jocie
เบราว์เซอร์บางตัวพยายามวางตำแหน่งเคอร์เซอร์ระหว่างmouseup
หรือclick
เหตุการณ์ สิ่งนี้สมเหตุสมผลแล้วเนื่องจากคุณอาจต้องการเริ่มเครื่องหมายรูปหมวกในตำแหน่งเดียวและลากเพื่อเน้นข้อความบางส่วน ไม่สามารถกำหนดตำแหน่งลูกศรได้จนกว่าคุณจะยกเมาส์ขึ้นจริง ดังนั้นฟังก์ชั่นที่จัดการfocus
จะโชคชะตาที่จะตอบสนองเร็วเกินไปออกจากเบราว์เซอร์เพื่อแทนที่ตำแหน่งของคุณ
แต่ถูคือเราต้องการจัดการกับเหตุการณ์โฟกัส มันช่วยให้เรารู้ว่าครั้งแรกที่มีคนเข้ามาในสนาม หลังจากจุดนั้นเราไม่ต้องการแทนที่พฤติกรรมการเลือกของผู้ใช้ต่อไป
การแก้ไขปัญหา:
แต่ภายในfocus
ตัวจัดการเหตุการณ์เราสามารถแนบผู้ฟังสำหรับเหตุการณ์click
(คลิกเข้า) และkeyup
(แท็บใน) แทนเหตุการณ์ที่กำลังจะเริ่มขึ้น
หมายเหตุ : การกดคีย์ของเหตุการณ์แท็บจะเริ่มขึ้นจริงในฟิลด์อินพุตใหม่ไม่ใช่คีย์ก่อนหน้า
เราต้องการไฟเหตุการณ์เพียงครั้งเดียว เราสามารถใช้.one("click keyup)
แต่ตอนนี้จะเรียกตัวจัดการเหตุการณ์ครั้งสำหรับแต่ละประเภทเหตุการณ์ เราจะเรียกฟังก์ชันของเราแทนทันทีที่กดปุ่มเม้าส์หรือคีย์ สิ่งแรกที่เราจะทำคือลบตัวจัดการสำหรับทั้งสอง ด้วยวิธีนี้มันจะไม่สำคัญว่าเราจะแท็บหรือ moused ในฟังก์ชั่นควรดำเนินการเพียงครั้งเดียว
หมายเหตุ : เบราว์เซอร์ส่วนใหญ่เลือกข้อความทั้งหมดในระหว่างเหตุการณ์แท็บ แต่เมื่อanimatedgif ชี้ให้เห็นเรายังคงต้องการจัดการkeyup
เหตุการณ์ไม่เช่นนั้นmouseup
กิจกรรมจะยังคงวนเวียนอยู่ตลอดเวลาที่เราแท็บเราฟังทั้งคู่เพื่อให้เราสามารถเปลี่ยนได้ ปิดผู้ฟังทันทีที่เราประมวลผลการเลือก
ตอนนี้เราสามารถโทรหาselect()
หลังจากที่เบราว์เซอร์ทำการเลือกเพื่อให้แน่ใจว่าจะแทนที่พฤติกรรมเริ่มต้น
ในที่สุดเพื่อการปกป้องเป็นพิเศษเราสามารถเพิ่มเนมสเปซของเหตุการณ์ในmouseup
และkeyup
ฟังก์ชั่นเพื่อให้.off()
วิธีการไม่ลบผู้ฟังอื่น ๆ ที่อาจจะเล่น
ผ่านการทดสอบใน IE 10+, FF 28+ และ Chrome 35+
อีกทางเลือกหนึ่งถ้าคุณต้องการขยาย jQuery ด้วยฟังก์ชั่นที่เรียกonce
ว่าจะทำงานหนึ่งครั้งสำหรับเหตุการณ์ใด ๆ :
$.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);
});
};
จากนั้นคุณสามารถลดความซับซ้อนของรหัสเพิ่มเติมเช่นนี้:
$("input").focus(function(){
$(this).once("click keyup", function(e){
$(this).select();
});
});