jQuery: vuurklik() voor gebeurtenis vervagen()

Ik heb een invoerveld waarin ik een suggestie voor automatisch aanvullen probeer te doen. Code ziet eruit als

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

Bij de blur()-gebeurtenis van input wil ik de div van de resultaten verbergen:

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

Als ik iets in mijn invoer schrijf, stuur ik een verzoek naar de server en krijg ik een json-antwoord, parseer ik het in de ul->li-structuur en plaats ik deze ul in mijn #myresultsdiv.

Als ik op dit geparseerde li-element klik, wil ik de waarde van li instellen op invoer en #myresultsdiv

verbergen

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

Alles gaat goed, maar wanneer ik op mijn li blur()-gebeurtenis klik voordat click()wordt geactiveerd, krijgt de waarde van de invoer de html van li niet.

Hoe kan ik een click()-gebeurtenis instellen vóór blur()?


Antwoord 1, autoriteit 100%

Oplossing 1

Luister naar mousedownin plaats van click.

De gebeurtenissen mousedownen blurvinden na elkaar plaats wanneer u op de muisknop drukt, maar clickvindt alleen plaats wanneer u deze loslaat.

Oplossing 2

U kunt preventDefault()in mousedownom te voorkomen dat de vervolgkeuzelijst de focus steelt. Het kleine voordeel is dat de waarde wordt geselecteerd wanneer de muisknop wordt losgelaten, en dat is hoe native select-componenten werken. 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();
});

Antwoord 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();
}

FIDDLE


Antwoord 3

Ik heb met dit probleem te maken gehad en het gebruik van mousedownis geen optie voor mij.

Ik heb dit opgelost door setTimeoutte gebruiken in de handlerfunctie

       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');
        });

Antwoord 4

Ik heb zojuist een vergelijkbare vraag beantwoord: https://stackoverflow.com/a/46676463/227578

Een alternatief voor de mousedown-oplossingen is om vervagingsgebeurtenissen te negeren die worden veroorzaakt door op specifieke elementen te klikken (d.w.z. sla in uw vervagingshandler de uitvoering over als dit het gevolg is van het klikken op een specifiek element).

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

Antwoord 5

Muisedown Solutions werkt niet voor mij, wanneer ik op niet-knopelementen klik. Dus hier is wat ik heb gedaan met een blur-functie in mijn code:

.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;
*/
});

Other episodes