เมื่อทำการพัฒนาเว็บ เรามักจะใช้กิจกรรมปิดเพจแบบ onbeforeunload ซึ่งจะทำให้ผู้ใช้สามารถเลือกที่จะยกเลิกการปิดได้ เช่น โปรแกรมแก้ไขบล็อกนี้ หากผู้ใช้เลือกที่จะออก เหตุการณ์ onunload จะถูกทริกเกอร์ตามธรรมชาติ แต่หากผู้ใช้เลือกที่จะยกเลิก จะตรวจจับได้อย่างไร
เราถือว่าหน้าหนึ่งออกจากเหตุการณ์การยกเลิกที่เรียกว่า onunloadcancel แน่นอนว่าเหตุการณ์นี้ควรจะเริ่มทำงานหลังจากที่ผู้ใช้กดปุ่มยกเลิกของกล่องโต้ตอบ แต่กระบวนการทริกเกอร์ในการปิดกล่องโต้ตอบพร้อมท์นั้นไม่ใช่เรื่องง่าย ก่อนอื่นมาทบทวนกระบวนการกันก่อน:
คัดลอกรหัสรหัสดังต่อไปนี้:
window.onbeforeunload = ฟังก์ชั่น ()
-
กลับ "จะออกไปจริงๆเหรอ?";
-
เมื่อผู้ใช้พร้อมที่จะออกจากเพจ (เช่น การกดปุ่มปิด หรือการรีเฟรชเพจ ฯลฯ) เหตุการณ์ onbeforeunload จะถูกทริกเกอร์ สคริปต์ของเราไม่สามารถตัดสินใจได้ว่าจะป้องกันไม่ให้เพจปิดในเหตุการณ์นี้หรือไม่ สิ่งเดียวที่สามารถทำได้คือการส่งคืนสตริงนี้เท่านั้น สตริงนี้จะปรากฏเป็นข้อความอธิบายในกล่องโต้ตอบการเลือกปิดเท่านั้น . แต่จะเลือกอันไหนเราไม่มีทางรู้ได้
อย่างไรก็ตาม หากเราวิเคราะห์ปัญหานี้อย่างรอบคอบ จริงๆ แล้วจะไม่เป็นเช่นนั้น หากผู้ใช้เลือกที่จะปิดเพจจริงๆ โค้ดที่ทำงานอยู่ทั้งหมดจะหายไป และหากผู้ใช้ยังอยู่ในเพจต่อไป ระบบจะถือว่าไม่มีอะไรเกิดขึ้น ยกเว้นเหตุการณ์ก่อนยกเลิกการโหลด ดังนั้นเราจึงทำเคล็ดลับเล็กน้อยในเหตุการณ์ onbeforeunload และลงทะเบียนตัวจับเวลาที่นี่ซึ่งจะเริ่มหลังจากผ่านไปสองสามมิลลิวินาที หากเพจถูกปิดจริงๆ แน่นอนว่าตัวจับเวลาจะไม่ถูกต้อง เพจนั้นก็จะยังคงอยู่ตรงนั้นและความล่าช้า ไม่กี่มิลลิวินาทีจะไม่มีข้อผิดพลาดในเหตุการณ์การโต้ตอบอินเทอร์เฟซแบบอะซิงโครนัสโดยเนื้อแท้นี้
คัดลอกรหัสรหัสดังต่อไปนี้:
<ภาษาสคริปต์ = "จาวาสคริปต์">
window.onbeforeunload = ฟังก์ชั่น ()
-
setTimeout (ยกเลิกการโหลดยกเลิก, 10);
กลับ "จะออกไปจริงๆเหรอ?";
-
window.onunloadcancel = ฟังก์ชั่น()
-
alert("ยกเลิกการออก");
-
</สคริปต์>
เราใช้ setTimeout และดีเลย์ 10ms เพื่อดำเนินการ onunloadcancel หากปิดเพจจริงๆ ตัวจับเวลาจะถูกทำลายแน่นอน ไม่เช่นนั้น ให้ดำเนินการต่อ แต่ในระหว่างการทดสอบพบว่า FireFox มีข้อบกพร่องสองประการ:
บางครั้งเมื่อกดปุ่มปิด onunloadcancel จะถูกดำเนินการด้วย และกล่องโต้ตอบจะกะพริบ หากคุณเปลี่ยนเป็น while(1); เบราว์เซอร์จะยังคงค้างอยู่ ซึ่งหมายความว่า onunloadcancel จะถูกดำเนินการจริง แต่จะทำลายอินเทอร์เฟซเท่านั้น แต่ไม่หยุดการทำงานของสคริปต์ชั่วคราว
หากคุณออกโดยการรีเฟรชเพจ onbeforeunload จะถูกดำเนินการเพียงครั้งเดียว แต่หากคุณคลิกปุ่ม X เพื่อปิดเพจ onbeforeunload จะถูกดำเนินการสองครั้ง ดังนั้นเราจึงยังต้องปรับปรุงให้เข้ากันได้กับ FF
คัดลอกรหัสรหัสดังต่อไปนี้:
<ภาษาสคริปต์ = "จาวาสคริปต์">
var_t;
window.onbeforeunload = ฟังก์ชั่น ()
-
setTimeout(ฟังก์ชั่น(){_t = setTimeout(onunloadcancel, 0)}, 0);
กลับ "จะออกไปจริงๆเหรอ?";
-
window.onunloadcancel = ฟังก์ชั่น ()
-
เคลียร์ไทม์เอาต์(_t);
alert("ยกเลิกการออก");
-
</สคริปต์>
มีการใช้วิธีการที่นี่ซึ่งฉันไม่สามารถอธิบายเหตุผลได้ ควรถือเป็นการแฮ็กเพื่อแก้ไขข้อบกพร่องใน FF