jQuery: fire click () ก่อนเหตุการณ์เบลอ ()


135

ฉันมีช่องป้อนข้อมูลซึ่งฉันพยายามให้คำแนะนำในการเติมข้อความอัตโนมัติ รหัสดูเหมือน

<input type="text" id="myinput">
<div id="myresults"></div>

ในblur()เหตุการณ์ของอินพุตฉันต้องการซ่อนผลลัพธ์ 'div:

$("#myinput").live('blur',function(){
     $("#myresults").hide();
});

เมื่อฉันเขียนบางสิ่งลงในอินพุตของฉันฉันส่งคำขอไปยังเซิร์ฟเวอร์และได้รับการตอบสนอง json แยกวิเคราะห์เป็นโครงสร้าง ul-> li และใส่ ul นี้ไว้ใน#myresultsdiv ของฉัน

เมื่อฉันคลิกไปที่องค์ประกอบ li ที่แยกวิเคราะห์นี้ฉันต้องการตั้งค่าจาก li เป็นอินพุตและซ่อน#myresultsdiv

$("#myresults ul li").live('click',function(){
     $("#myinput").val($(this).html());
     $("#myresults").hide();
});

ทุกอย่างเป็นไปด้วยดี แต่เมื่อฉันคลิกไปที่blur()เหตุการณ์li ของฉันจะเริ่มทำงานก่อนclick()และค่าของอินพุตไม่ได้รับ html ของ li

จะตั้งค่าclick()เหตุการณ์ก่อนได้blur()อย่างไร?


แล้วทำไมคุณถึงใช้ฟังก์ชั่นเบลอ? เมื่อความต้องการของคุณเต็มแล้วจากฟังก์ชันคลิก
Owais Iqbal

สิ่งนี้อาจไม่เปลี่ยนลำดับที่เหตุการณ์ของคุณกำลังเริ่มทำงาน แต่หากblurกำลังเริ่มทำงานจริงๆหลังจากที่คุณคลิกที่ไฟล์liคุณอาจไม่จำเป็นต้องดำเนินการ$("#myresults").hide()ในตัวจัดการการคลิก สิ่งที่ดูเหมือนว่ากำลังเกิดขึ้นคือ$(this).html()กำลังส่งคืนสตริงว่าง คุณสามารถlogหรือalert $(this).html()เพื่อให้แน่ใจ?
veeTrain

@OwaisIqbal บางครั้งไม่มีผลลัพธ์บางครั้งผู้ใช้ไม่ต้องการเลือกอะไรจากคำแนะนำบางครั้งผู้ใช้ไม่ต้องการใช้อินพุตนี้อีกต่อไป แต่ฉันต้องซ่อนผลลัพธ์ที่ไม่ได้ใช้
Egor Sazanovich

@veeTrain มีการดำเนินการมากมายในตัวจัดการของฉันฉันเพิ่งย่อให้เล็กที่สุดเพื่อให้เข้าใจปัญหาในคำถามของฉันได้ง่าย ps ฉันพยายามเพิ่มจุดเฝ้าดูใน firebug บนblur()และclick()ตัวจัดการไม่มีการดำเนินการใด ๆ หลังจากblur()สิ้นสุด
Egor Sazanovich

ดูเหมือนว่าคุณต้องจัดคิวฟังก์ชัน ลองดูที่หน้านี้: stackoverflow.com/questions/1058158/… . ส่วน First-In-First-Out (FIFO) อาจเกี่ยวข้องกับคุณ
Patriotec

คำตอบ:


315

โซลูชันที่ 1

ฟังmousedownแทนclick.

mousedownและblurเหตุการณ์ที่เกิดขึ้นหลังจากนั้นอีกหนึ่งเมื่อคุณกดปุ่มเมาส์ แต่clickเกิดขึ้นเฉพาะเมื่อคุณปล่อยมัน

โซลูชันที่ 2

คุณสามารถpreventDefault()ในmousedownเพื่อป้องกันการเลื่อนลงจากการมุ่งเน้นการขโมย ข้อได้เปรียบเล็กน้อยคือค่าจะถูกเลือกเมื่อปล่อยปุ่มเมาส์ซึ่งเป็นวิธีการทำงานของส่วนประกอบการเลือกดั้งเดิม JSFiddle

$('input').on('focus', function() {
    $('ul').show();
}).on('blur', function() {
    $('ul').hide();
});

$('ul').on('mousedown', function(event) {
    event.preventDefault();
}).on('click', 'li', function() {
    $('input').val(this.textContent).blur();
});

13
โซลูชันที่ 1 ใช้ได้ผลสำหรับฉันในสถานการณ์เดียวกันนี้! เปลี่ยนง่าย! ขอบคุณ :)
จอน

ขอบคุณ :) แต่คุณอธิบายได้ไหมว่าทำไมการฟัง mousedown แทนการคลิกจึงทำงานเหมือนมีเสน่ห์
Mudassir Ali

3
@MudassirAli เพราะเหตุการณ์มูสดาวน์มาก่อนเบลอและคลิกมาทีหลัง jsfiddle.net/f3BKP
Alexey Lebedev

โซลูชัน # 1 อยู่ในความคิดของฉันเป็นทางเลือกที่ดีกว่า ง่ายและมีประสิทธิภาพ การหมดเวลาจะหมายถึงการใช้รหัสมากขึ้น + พื้นที่มากขึ้นสำหรับพฤติกรรมที่ไม่คาดคิด (หมดเวลานานแค่ไหนนานพอที่จะลงทะเบียนคลิก แต่ไม่นานเกินไปที่จะสับสนการใช้งาน ... )
cw24

5
โซลูชัน # 2 เป็นสิ่งที่ชาญฉลาด ฉันจะไม่คิดออก! ขอบคุณ
Tobia

2
$(document).on('blur', "#myinput", hideResult);

$(document).on('mousedown', "#myresults ul li", function(){
     $(document).off('blur', "#myinput", hideResult); //unbind the handler before updating value
     $("#myinput").val($(this).html()).blur(); //make sure it does not have focus anymore
     hideResult(); 
     $(document).on('blur', "#myinput", hideResult);  //rebind the handler if needed
});

function hideResult() {
     $("#myresults").hide();
}

ซอ


2

ฉันประสบปัญหานี้และการใช้mousedownไม่ใช่ตัวเลือกสำหรับฉัน

ฉันแก้ไขสิ่งนี้โดยใช้setTimeoutในฟังก์ชันตัวจัดการ

        elem1.on('blur',function(e) {

            var obj = $(this);

            // Delay to allow click to execute
            setTimeout(function () {
                if (e.type == 'blur') {

                  // Do stuff here

                }
            }, 250);
        });

        elem2.click( function() {
            console.log('Clicked');
        });

2

ฉันเพิ่งตอบคำถามที่คล้ายกัน: https://stackoverflow.com/a/46676463/227578

อีกทางเลือกหนึ่งของโซลูชันแบบมูสดาวน์คือให้ละเว้นเหตุการณ์เบลอที่เกิดจากการคลิกองค์ประกอบที่เฉพาะเจาะจง (เช่นในตัวจัดการการเบลอของคุณให้ข้ามการดำเนินการหากเป็นผลมาจากการคลิกองค์ประกอบใดองค์ประกอบหนึ่ง)

$("#myinput").live('blur',function(e){
     if (!e.relatedTarget || !$(e.relatedTarget).is("#myresults ul li")) {
         $("#myresults").hide();
     }
});

ในกรณีของฉัน event.relatedTarget ส่งคืนค่าว่างความคิดใด ๆ ที่เป็นไปได้
gaurav5430

ตกลงมีคำตอบที่นี่: stackoverflow.com/questions/42764494/…
gaurav5430

0

โซลูชันการวางเมาส์ไม่ได้ผลสำหรับฉันเมื่อฉันคลิกที่องค์ประกอบที่ไม่ใช่ปุ่ม นี่คือสิ่งที่ฉันทำกับฟังก์ชันเบลอในโค้ดของฉัน:

.on("blur",":text,:checkbox,:radio,select",function() {
/*
* el.container 
* container, you want detect click function on.
*/
            var outerDir = el.container.find(':hover').last();
            if (outerDir.length) {
                if ($.inArray(outerDir.prop('tagName'), ["A","SELECT"] ) != -1 || outerDir.prop('type') == 'button' || outerDir.prop('type') == 'submit') {
                    outerDir.click();
                }
                if (outerDir.prop('type') == 'checkbox') {
                    outerDir.change();
                }
                return false;
            }
/*          
* YOUR_BLUR_FUNCTION_HERE;
*/
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.