jQuery: Feuer click () vor dem Ereignis blur ()

134

Ich habe ein Eingabefeld, in dem ich versuche, einen Vorschlag zur automatischen Vervollständigung zu machen. Code sieht aus wie

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

Beim blur()Ereignis der Eingabe möchte ich das div der Ergebnisse ausblenden:

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

Wenn ich etwas in meine Eingabe schreibe, sende ich eine Anfrage an den Server und erhalte eine json-Antwort, analysiere sie in die ul-> li-Struktur und lege diese ul in mein #myresultsdiv.

Wenn ich auf dieses analysierte li-Element klicke, möchte ich den Wert von li festlegen, um #myresultsdiv einzugeben und auszublenden

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

Alles läuft gut, aber wenn ich auf mein li- blur()Ereignis klicke, wird es vorher ausgelöst click()und der Wert der Eingabe erhält nicht das HTML von li.

Wie kann ich eine click()Veranstaltung vorher einrichten blur()?

Egor Sazanovich
quelle
Warum verwenden Sie in diesem Fall die Unschärfefunktion? wenn Ihr Bedarf bereits durch Klickfunktion erfüllt ist.
Owais Iqbal
Dies ändert wahrscheinlich nichts an der Reihenfolge, in der Ihre Ereignisse ausgelöst werden. Wenn Sie blurjedoch nach dem Klicken auf ein Ereignis wirklich ausgelöst werden li, müssen Sie es wahrscheinlich nicht $("#myresults").hide()im Klick-Handler ausführen . Es scheint so, $(this).html()als würde eine leere Zeichenfolge zurückgegeben. Könnten Sie logoder alert $(this).html()um sicher zu gehen?
VeeTrain
@OwaisIqbal manchmal gibt es keine Ergebnisse, manchmal möchte der Benutzer nichts aus Vorschlägen auswählen, manchmal möchte der Benutzer diese Eingabe nicht mehr verwenden, aber ich muss das nicht verwendete Ergebnis ausblenden
Egor Sazanovich
@veeTrain Es gibt viele Aktionen in meinen Handlern. Ich habe sie nur minimiert, um das Problem in meiner Frage leichter zu verstehen. ps Ich habe versucht, einen Überwachungspunkt in Firebug blur()und click()Handler hinzuzufügen , es gibt keine Aktionen nach dem blur()Ende
Egor Sazanovich
Es sieht so aus, als müssten Sie die Funktionen in die Warteschlange stellen. Schauen Sie sich diese Seite an: stackoverflow.com/questions/1058158/… . Der FIFO-Teil (First-In-First-Out) kann sich auf Sie beziehen
Patriotec,

Antworten:

312

Lösung 1

Hören Sie mousedownstatt click.

Die mousedownund blur-Ereignisse treten nacheinander auf, wenn Sie die Maustaste drücken, treten jedoch clicknur auf, wenn Sie sie loslassen.

Lösung 2

Sie können preventDefault()in mousedownder Drop - Down - Block von Fokus zu stehlen. Der leichte Vorteil ist, dass der Wert ausgewählt wird, wenn die Maustaste losgelassen wird. So funktionieren native Auswahlkomponenten. 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();
});
Alexey Lebedev
quelle
12
Lösung 1 hat bei mir in der gleichen Situation funktioniert! Einfacher Wechsel! Vielen Dank :)
Jon
Vielen Dank :) Aber können Sie erklären, warum das Hören von Mousedown anstelle von Klicken wie ein Zauber wirkt?
Mudassir Ali
3
@MudassirAli, weil das Mousedown-Ereignis vor der Unschärfe und der Klick danach erfolgt. jsfiddle.net/f3BKP
Alexey Lebedev
Lösung 1 ist meiner Meinung nach die bessere Wahl. Einfach und effektiv. Zeitüberschreitung würde mehr Code bedeuten + mehr Raum für unerwartetes Verhalten (wie lange dauert eine Zeitüberschreitung? Lang genug, um den Klick zu registrieren, aber nicht zu lang, um die Verwendung zu verwirren ...).
CW24
5
Lösung Nr. 2 ist genial. Ich hätte es nie herausgefunden! Vielen Dank
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();
}

GEIGE

Adeneo
quelle
2

Ich war mit diesem Problem konfrontiert und die Verwendung mousedownist für mich keine Option.

Ich habe dies mit setTimeoutder Handler-Funktion gelöst

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

Ich habe gerade eine ähnliche Frage beantwortet: https://stackoverflow.com/a/46676463/227578

Eine Alternative zu den Mousedown-Lösungen besteht darin, Unschärfeereignisse zu ignorieren, die durch Klicken auf bestimmte Elemente verursacht werden (dh überspringen Sie in Ihrem Unschärfehandler die Ausführung, wenn Sie auf ein bestimmtes Element klicken).

$("#myinput").live('blur',function(e){
     if (!e.relatedTarget || !$(e.relatedTarget).is("#myresults ul li")) {
         $("#myresults").hide();
     }
});
dule
quelle
In meinem Fall gibt event.relatedTarget null zurück. Gibt es eine Idee, warum das so sein könnte?
Gaurav5430
ok, habe die Antwort hier: stackoverflow.com/questions/42764494/…
gaurav5430
0

Mousedown-Lösungen funktionieren bei mir nicht, wenn ich auf Elemente ohne Schaltflächen klicke. Folgendes habe ich mit der Unschärfefunktion in meinem Code gemacht:

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