คำอธิบายปัญหา
ฉันหวังว่าเมื่อเมาส์ย้ายไปที่ ID1, ID2 จะปรากฏขึ้นและเมื่อเมาส์ออกจาก ID1, ID2 จะปรากฏขึ้น คำถามมีดังนี้:
1. เมื่อเมาส์เคลื่อนที่จาก ID1 เป็น ID2 ID จะเปลี่ยนจากจอแสดงผลเป็นไม่แสดงแล้วเปลี่ยนเพื่อแสดง
2. เมื่อเมาส์เคลื่อนที่จาก ID2 ไปยัง ID1 การแสดงผลของ ID2 จะไม่ใช่การแสดงและจากนั้นจะกลายเป็นจอแสดงผล
สิ่งที่ฉันต้องการคือเมื่อเมาส์เคลื่อนที่บน ID1 หรือ ID2, ID2 จะปรากฏตัวต่อไปโดยไม่ต้องเปลี่ยน
<script type = "text/javascript" src = "https://code.jquery.com/jquery-1.12.4.js"> </script> <div id = "id1"> <div id = "id2"> </div> type = "text/javascript"> $ ("#id1"). mouseover (function () {$ (this) .children (). fadein (1,000);}). mouseout (function () {$ (this) .children (). fadeout (1000);};การแก้ปัญหา
การวิเคราะห์ปัญหาเบื้องต้นคือเมื่อเมาส์ย้ายจาก ID1 เป็น ID2 เมาส์ที่เหลือจาก ID2 ถึง ID1 และเหตุการณ์เมาส์ถูกเรียกใช้สำหรับ ID1 ดังนั้นการแสดง ID2 จึงไม่ได้แสดง จากนั้นเมาส์ก็ย้ายไปที่ ID2 และเหตุการณ์ MouseOver ถูกเรียกใช้ใน ID2 เนื่องจากกลไกฟองก่อนที่ MouseOver บน ID2 จะเป็นฟองเป็น ID1 เหตุการณ์ MouseOver บน ID1 จะถูกทริกเกอร์และจากนั้น ID2 ก็เปลี่ยนจากการไม่แสดง ในทำนองเดียวกันเมื่อเมาส์เคลื่อนที่จาก ID2 เป็น ID1 เหตุการณ์เมาส์จะถูกเรียกใช้สำหรับ ID2 หรือเป็นเพราะกลไกฟองที่เหตุการณ์ MouseOut ถูกส่งไปยัง ID1 และการเปลี่ยนแปลง ID2 จากการแสดงเป็นแบบไม่แสดง จากนั้นก่อนที่เมาส์จะย้ายไปยัง ID1 เหตุการณ์ MouseOver จะถูกทริกเกอร์และจากนั้น ID2 จะไม่แสดงเพื่อแสดง
ดูเหมือนว่าปัญหาข้างต้นจะต้องได้รับการแก้ไขโดยการปิดกั้นเมาส์จาก ID1 เมื่อเมาส์เคลื่อนที่จาก ID1 เป็น ID2; เมื่อเมาส์เคลื่อนที่จาก ID2 เป็น ID1 การปิดกั้นเมาส์ออกจาก ID2 จาก ID2 เป็น ID1 ป้องกันไม่ให้เมาส์ออกจาก ID2 จาก Bubbled เหนือ ID1 จากนั้นปัญหาไม่สามารถแก้ไขได้เพียงแค่ป้องกันฟอง
เพื่อแก้ปัญหาดังกล่าว jQuery ให้วิธี Mouseenter และ Mouseleave ดังนั้นรหัส JS จึงเปลี่ยนเป็นต่อไปนี้ซึ่งแก้ไขปัญหาได้ดีมาก
$ ("#id1"). mouseenter (function () {$ (นี่) .children (). fadein (1,000);}). Mouseleave (ฟังก์ชั่น () {$ (นี่) .children (). fadeout (1,000);});หลายสถานที่แนะนำ Mouseenter, Mouseleave, Mouseover และ Mouseout ดังนั้นฉันจึงคัดลอกและวางหนึ่ง
-
1. MUOSEOVER และ MOUSEENTER
เหตุการณ์ MouseOver จะถูกกระตุ้นโดยไม่คำนึงว่าตัวชี้เมาส์จะผ่านองค์ประกอบที่เลือกหรือองค์ประกอบลูก
เหตุการณ์ Mouseenter จะถูกเรียกใช้ก็ต่อเมื่อตัวชี้เมาส์ผ่านองค์ประกอบที่เลือก
2. Mouseout และ Mouseleave
เหตุการณ์ Mouseout จะถูกทริกเกอร์ไม่ว่าตัวชี้เมาส์จะออกจากองค์ประกอบที่เลือกหรือองค์ประกอบเด็กใด ๆ
เหตุการณ์ Mouseleave จะถูกเรียกใช้ก็ต่อเมื่อตัวชี้เมาส์ออกจากองค์ประกอบที่เลือก
-
ปรากฏการณ์นี้เป็นปรากฏการณ์นี้ แต่กระบวนการนี้ค่อนข้างคลุมเครือ ความเข้าใจของฉันมีดังนี้:
เมื่อตัวชี้เมาส์ย้ายไปยังองค์ประกอบที่เลือกเหตุการณ์ MouseOver จะถูกเรียกใช้ ทุกคนรู้ว่าเมื่อตัวชี้เมาส์ย้ายจากองค์ประกอบที่เลือกไปยังองค์ประกอบลูกเหตุการณ์เมาส์ขององค์ประกอบที่เลือกจะถูกเรียกใช้ก่อนจากนั้นเหตุการณ์ MouseOver ขององค์ประกอบเด็กจะถูกฟองเป็นองค์ประกอบที่เลือก ในเวลานี้มันเทียบเท่ากับองค์ประกอบที่เลือกก่อนที่จะดำเนินการจัดกิจกรรม MouseOut แล้วดำเนินการจัดกิจกรรม MouseOver
สำหรับการตรวจสอบให้เปลี่ยนรหัสเป็นต่อไปนี้
<script type = "text/javascript" src = "https://code.jquery.com/jquery-1.12.4.js"> </script> <div id = "id1"> <div id = "id2"> </div> type = "text/javascript"> $ ("#id1"). mouseover (function () {// $ (นี่) .children (). fadein (1000); console.log ('a');}). mouseout (function () {// $ (นี่)ย้ายเมาส์จากหน้าไปยัง ID1 จากนั้นย้ายจาก ID1 ไปยัง ID2 เอาต์พุตคอนโซลมีดังนี้
จะเห็นได้ว่า ID1 ได้เรียกเหตุการณ์ MouseOver, Mouseout และ MouseOver ซึ่งเหมือนกับที่วิเคราะห์ไว้ข้างต้น
การวิเคราะห์การใช้งาน Mouseenter และ Mouseleave
การวิเคราะห์หลัก
จากการวิเคราะห์ข้างต้นเราจะเห็นได้ว่าเพื่อให้ได้ผลของ Mouseenter และ Mouseleave เมื่อเมาส์เคลื่อนที่จากองค์ประกอบที่เลือกไปยังองค์ประกอบลูกองค์ประกอบที่เลือกไม่ได้ดำเนินการเหตุการณ์ Mouseout และไม่ดำเนินการเหตุการณ์ MouseOver ที่ฟองย่อย เมื่อเมาส์เคลื่อนที่จากองค์ประกอบลูกองค์ประกอบที่เลือกไปยังองค์ประกอบที่เลือกองค์ประกอบที่เลือกจะไม่ดำเนินการเหตุการณ์ MouseOver และไม่ดำเนินการเหตุการณ์ MouseOut ที่ฟองย่อย
เพื่อให้ได้เอฟเฟกต์ข้างต้นเราจำเป็นต้องมีแอตทริบิวต์ที่เกี่ยวข้องกับเป้าหมายของวัตถุเหตุการณ์ซึ่งใช้เพื่อตัดสินคุณลักษณะของโหนดที่เกี่ยวข้องของโหนดเป้าหมายของ MouseOver และ Mouseout พูดง่ายๆเมื่อเหตุการณ์ MouseOver ถูกทริกเกอร์แอตทริบิวต์ที่เกี่ยวข้องจะแสดงถึงโหนดที่เมาส์เพิ่งออกไปและเมื่อเหตุการณ์ MouseOut ถูกทริกเกอร์มันแสดงถึงวัตถุที่เมาส์เคลื่อนที่ไป เนื่องจาก MSIE ไม่สนับสนุนคุณสมบัตินี้จึงมีคุณสมบัติทดแทน ได้แก่ จากการเลือกตั้งและการเลือก นอกจากนี้เรายังต้องใช้วิธีการที่จะตรวจสอบว่าวัตถุมีอยู่ในวัตถุอื่นหรือไม่
ด้วยวิธีนี้เมื่อเมาส์เคลื่อนที่คุณต้องตัดสินสองตัวต่อไปนี้
1. Call MouseOver คุณจะต้องพิจารณาว่าเป้าหมายที่เกี่ยวข้องเป็นองค์ประกอบลูกขององค์ประกอบที่เลือกหรือไม่ ถ้าเป็นเช่นนั้นมันจะไม่ถูกดำเนินการ (เมื่อย้ายจากองค์ประกอบลูกองค์ประกอบที่เลือกไปยังองค์ประกอบที่เลือก MouseOver จะไม่ถูกดำเนินการเมื่อย้ายจากองค์ประกอบที่เลือกไปยังองค์ประกอบองค์ประกอบลูกที่เลือก
2. โทรหา Mouseout คุณจะต้องพิจารณาว่าองค์ประกอบลูกของเป้าหมายที่เกี่ยวข้องถูกเลือกหรือไม่ ถ้าเป็นเช่นนั้นมันจะไม่ถูกดำเนินการ (เมื่อย้ายจากองค์ประกอบลูกองค์ประกอบที่เลือกไปยังองค์ประกอบที่เลือกเม้าส์เดือดจากองค์ประกอบลูกจะไม่ถูกดำเนินการเมื่อย้ายจากองค์ประกอบที่เลือกไปยังองค์ประกอบองค์ประกอบลูกที่เลือก
กระบวนการดำเนินการ
ตรวจสอบว่ามีความสัมพันธ์แบบรวมระหว่างสององค์ประกอบ
ฟังก์ชั่นประกอบด้วย encapsulated ใน jQuery ดังนี้
มันสามารถทำให้ง่ายขึ้นดังนี้
// ตัดสินว่าทั้งสองมี bfunction มี (a, b) {return a.contains หรือไม่? a! = b && a.contains (b): !! (A.ComparedocumentPosition (b) & 16);}ความรู้เบื้องต้นเกี่ยวกับการเปรียบเทียบตำแหน่ง
วิธีนี้เป็นส่วนหนึ่งของข้อกำหนด DOM ระดับ 3 ช่วยให้คุณสามารถกำหนดตำแหน่งซึ่งกันและกันระหว่างโหนด DOM 2 โหนด วิธีนี้มีประสิทธิภาพมากกว่า. contains () แอปพลิเคชั่นหนึ่งที่เป็นไปได้ของวิธีนี้คือการเรียงลำดับโหนด DOM เป็นลำดับโดยละเอียดและแม่นยำ ข้อมูลที่ส่งคืนโดย Nodea.ComparedocumentPosition (NODEB) อธิบายไว้ดังนี้:
หมายเลขบิตหมายถึง
ผ่านข้างต้นเราสามารถเข้าใจได้ว่าทำไมเราควรเขียนเป็น A. -comparedocumentPosition (B) & 16 เพราะถ้าโหนด A มีโหนด B, 16 จะถูกส่งคืน 16 & 16 = 1 จะถูกส่งคืนและผลลัพธ์จะเป็น 0 ในกรณีอื่น ๆ
รับเป้าหมายที่เกี่ยวข้องสำหรับความเข้ากันได้
เพื่อให้เข้ากันได้กับเบราว์เซอร์ต่างๆโปรดดูที่ซอร์สโค้ด jQuery เขียนรหัสต่อไปนี้เพื่อรับแอตทริบิวต์ที่เกี่ยวข้องกับเป้าหมายของ MouseOver และโหนดเหตุการณ์ MouseOut
ฟังก์ชั่น getRelated (e) {var ที่เกี่ยวข้อง; var type = e.type.toLowerCase (); // รับชื่อเหตุการณ์ที่นี่ถ้า (type == 'mouseover') {เกี่ยวข้อง = e.RelatedTarget || e.fromelement} อื่น -ปรับปรุง Mouseover และ Mouseout
ปรับปรุง Mouseover และ Mouseout เพื่อให้ได้เอฟเฟกต์ Mouseenter และ Mouseleave ที่ดีขึ้นรหัสทั้งหมดมีดังนี้
<! doctype html> <html> <head> <title> </title> </head> <body> <div id = "id1"> <div id = "id2"> </div> </div> <script type = "text/javascript" src = "https:/code.com type = "text/javascript"> // ตัดสินว่าสอง A มี bfunction มี (a, b) {return a.contains หรือไม่? a! = b && a.contains (b): !! (a.comparedocumentposition (b) & 16);} ฟังก์ชั่น getRelated (e) {var ที่เกี่ยวข้อง; var type = e.type.toLowerCase (); // รับชื่อเหตุการณ์ที่นี่ (type == 'mouseOver') if (type = 'mouseout') {เกี่ยวข้อง = e.RelatedTarget || e.toElement} return ที่เกี่ยวข้อง; } $ (function () {$ ("#id1"). mouseover (ฟังก์ชั่น (e) {// ปกป้องเมื่อเมาส์เคลื่อนที่ไปยัง ID1 var ที่เกี่ยวข้อง = getRelated (e); // ถ้าเกี่ยวข้องคือองค์ประกอบลูก ID2 ของ ID1 นั่นคือการเคลื่อนที่จากองค์ประกอบของเด็ก ดำเนินการถ้า (นี่! = ที่เกี่ยวข้อง &&! มี (นี้เกี่ยวข้อง)) {console.log ('mouseover');}}). mouseout (ฟังก์ชัน (e) {// ตัดสินว่าเมาส์ควรย้ายจาก ID1? var ที่เกี่ยวข้อง = getRelated (e); องค์ประกอบไม่มีการดำเนินการมิฉะนั้นการดำเนินการที่สอดคล้องกันจะดำเนินการถ้า (นี่! = เกี่ยวข้อง &&! มี (สิ่งนี้เกี่ยวข้อง)) {console.log ('mouseout');}});}); </script> </body> </html>ทดสอบเส้นทางการเคลื่อนไหวของเมาส์ดังแสดงในแผนภาพต่อไปนี้
ดังที่เห็นได้จากคอนโซล Mouseover และ Mouseout ในขณะนี้มีเอฟเฟกต์ Mouseenter และ Mouseleave พร้อมอุปกรณ์ครบครัน
การห่อหุ้มรหัส
หากคุณต้องการโหลด jQuery หรือเขียนตัวแทนจำนวนมากทุกครั้งที่คุณดำเนินการดังกล่าวมันจะเป็นงานที่น่าเบื่อ เพื่ออำนวยความสะดวกในการดำเนินงานในอนาคตบรรจุภัณฑ์ที่เหมาะสมจะดำเนินการจำลอง jQuery และสร้าง mouseenter และ Mouseleave ของคุณเอง รหัสถูกห่อหุ้มลงในไฟล์ dqmouse.js ดังนี้:
(ฟังก์ชั่น (w) {var dqmouse = function (obj) {// function body return ใหม่ dqmouse.fn.init (obj);} dqmouse.fn = dqmouse.prototype = {// obj = obj) this;}, มี: ฟังก์ชั่น (a, b) {return a.contains? if (type == 'mouseover') {เกี่ยวข้อง = e.RelatedTarget || e.fromelement} อื่นถ้า (type = 'mouseout') {เกี่ยวข้อง = e.RelatedTarget || e.toElement} กลับมาที่เกี่ยวข้อง; เกี่ยวข้อง = _self.getRelated (e); ถ้า (นี่! = ที่เกี่ยวข้อง &&! ! _self.contains (obj, ที่เกี่ยวข้อง)) {fn ();}} return _self;}} dqmouse.fn.init.prototype = dqmouse.fn; window.dqmouse = window. $$ = dqmouse;} (หน้าต่าง);ไฟล์ต้นฉบับที่เรียกว่ามีดังนี้:
<div id = "id1"> <div id = "id2"> </div> </div> <script type = "text/javascript" src = "dqmouse.js"> </script> <script type = "javascript"> var id1 = document.getElementById ('id1'); $$ (id1) .over (function () {console.log ('mouseover');}). out (ฟังก์ชั่น () {console.log ('mouseout');}); </script>ข้างต้นเป็นเนื้อหาที่เกี่ยวข้องเกี่ยวกับวิธีการแก้ปัญหาของ Mouseover และ Mouseout ที่ก่อให้เกิดหลายครั้งใน JS ที่บรรณาธิการแนะนำให้คุณรู้จัก ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน!