ค้นหาเว็บไซต์

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 ของคุณเองเพื่อจำลองอินพุตที่ถูกปิดใช้งาน แต่มีการควบคุมมากขึ้น

บทความที่เกี่ยวข้อง