javascript - เหตุการณ์บนอินพุตที่ถูกปิดใช้งาน
ปรากฏว่า <input> ที่ถูกปิดการใช้งานจะไม่ถูกจัดการโดยอีเวนต์ใด ๆ
มีวิธีใดที่จะหลีกเลี่ยงปัญหานี้ได้หรือไม่?
<input type="text" disabled="disabled" name="test" value="test" />
$(':input').click(function () {
$(this).removeAttr('disabled');
})
ที่นี่ ฉันต้องคลิกที่ช่องกรอกเพื่อเปิดใช้งานมัน แต่ถ้าฉันไม่เปิดใช้งาน ช่องกรอกนั้นไม่ควรถูกโพสต์
คำตอบ #1
องค์ประกอบที่ถูกปิดใช้งานจะไม่ทำให้เกิดเหตุการณ์เมาส์ เบราว์เซอร์ส่วนใหญ่จะส่งต่อเหตุการณ์ที่มาจากองค์ประกอบที่ถูกปิดใช้งานขึ้นไปตามต้นไม้ DOM ดังนั้นสามารถวางตัวจัดการเหตุการณ์บนองค์ประกอบคอนเทนเนอร์ได้ อย่างไรก็ตาม Firefox ไม่แสดงพฤติกรรมนี้ มันจะไม่ทำอะไรเลยเมื่อคุณคลิกที่องค์ประกอบที่ถูกปิดใช้งาน
ฉันนึกไม่ออกว่ามีวิธีแก้ปัญหาที่ดีกว่านี้ แต่เพื่อความเข้ากันได้กับเบราว์เซอร์ทุกตัวอย่างสมบูรณ์ คุณสามารถวางองค์ประกอบหนึ่งไว้ด้านหน้าของอินพุตที่ถูกปิดใช้งานและจับการคลิกบนองค์ประกอบนั้น นี่คือตัวอย่างที่ฉันหมายถึง:
<div style="display:inline-block; position:relative;">
<input type="text" disabled />
<div style="position:absolute; left:0; right:0; top:0; bottom:0;"></div>
</div>
jq :
$("div > div").click(function (evt) {
$(this).hide().prev("input[disabled]").prop("disabled", false).focus();
});
ตัวอย่าง: http://jsfiddle.net/RXqAm/170/ (อัปเดตให้ใช้ jQuery 1.7 โดยใช้ prop แทน attr)
คำตอบ #2
องค์ประกอบที่ถูกปิดใช้งาน "กิน" คลิกในเบราว์เซอร์บางตัว - พวกมันไม่ตอบสนองต่อคลิกเหล่านั้น และไม่อนุญาตให้ถูกจับโดยตัวจัดการเหตุการณ์ใด ๆ ทั้งบนองค์ประกอบหรือในคอนเทนเนอร์ใด ๆ ของมัน
ตามความคิดเห็นส่วนตัว วิธีที่ง่ายที่สุดและสะอาดที่สุดในการ "แก้ไข" สิ่งนี้ (ถ้าคุณจำเป็นต้องจับการคลิกบนองค์ประกอบที่ถูกปิดใช้งานจริงๆ เหมือนที่ผู้เริ่มกระทู้ทำ) คือเพียงเพิ่ม CSS ต่อไปนี้ลงในหน้าของคุณ:
input[disabled] {pointer-events:none}
สิ่งนี้จะทำให้การคลิกบนอินพุตที่ถูกปิดใช้งานตกลงไปยังองค์ประกอบแม่ ซึ่งคุณสามารถจับเหตุการณ์เหล่านั้นได้ตามปกติ (ถ้าคุณมีอินพุตที่ถูกปิดใช้งานหลายตัว คุณอาจต้องการวางแต่ละช่องไว้ในคอนเทนเนอร์ของตัวเอง ถ้ายังไม่ได้จัดวางในลักษณะนั้น - เช่น <span> หรือ <div> เพียงเพื่อให้ง่ายต่อการระบุว่าคลิกอินพุตที่ถูกปิดใช้งานตัวไหน)
ข้อเสียคือเทคนิคนี้น่าเสียดายที่จะใช้ไม่ได้กับเว็บเบราว์เซอร์เก่าที่ไม่สนับสนุนคุณสมบัติ CSS pointer-events (มันควรใช้งานได้ตั้งแต่ IE 11, FF v3.6, Chrome v4): caniuse.com/#search=pointer-events
หากคุณจำเป็นต้องรองรับเบราว์เซอร์รุ่นเก่า คุณจะต้องใช้คำตอบอื่น ๆ
คำตอบ #3
บางทีคุณอาจจะทำให้ฟิลด์เป็นแบบอ่านอย่างเดียว และเมื่อกดส่ง ปิดการใช้งานฟิลด์ทั้งหมดที่เป็นแบบอ่านอย่างเดียว
$(".myform").submit(function(e) {
$("input[readonly]").prop("disabled", true);
});
และอินพุต (+ สคริปต์) ควรเป็น
<input type="text" readonly="readonly" name="test" value="test" />
$('input[readonly]').click(function () {
$(this).removeAttr('readonly');
});
ตัวอย่างสด:
$(".myform").submit(function(e) {
$("input[readonly]").prop("disabled", true);
e.preventDefault();
});
$('.reset').click(function () {
$("input[readonly]").prop("disabled", false);
})
$('input[readonly]').click(function () {
$(this).removeAttr('readonly');
})input[readonly] {
color: gray;
border-color: currentColor;
}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="myform">
<input readonly="readonly" value="test" />
<input readonly="readonly" value="test" />
<input readonly="readonly" value="test" />
<input readonly="readonly" value="test" />
<input readonly="readonly" value="test" />
<input readonly="readonly" value="test" />
<input readonly="readonly" value="test" />
<input readonly="readonly" value="test" />
<input readonly="readonly" value="test" />
<button>Submit</button>
<button class="reset" type="button">Reset</button>
</form>คำตอบ #4
ฉันขอแนะนำอีกทางเลือกหนึ่ง - ใช้ CSS:
input.disabled {
user-select : none;
-moz-user-select : none;
-webkit-user-select : none;
color: gray;
cursor: pointer;
}
แทนที่จะใช้แอตทริบิวต์ disabled จากนั้นคุณสามารถเพิ่มแอตทริบิวต์ CSS ของคุณเองเพื่อจำลองอินพุตที่ถูกปิดใช้งาน แต่มีการควบคุมมากขึ้น
